diff --git a/lib/app/config.default.json b/lib/app/config.default.json deleted file mode 100644 index 6c61ae9..0000000 --- a/lib/app/config.default.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "debug": false, - "port": 1571, - "maxFileSize": 99999, - "exclude": - [ - "**/.DS_Store", - "node_modules/**", - "vendor/**", - ".git" - ] -} diff --git a/lib/app/site/models/file.js b/lib/app/file.js similarity index 98% rename from lib/app/site/models/file.js rename to lib/app/file.js index f0832fb..c4d1da7 100644 --- a/lib/app/site/models/file.js +++ b/lib/app/file.js @@ -2,7 +2,7 @@ // Depedencies const diff = require('diff') -const ids = require('../utils/ids.js') +const ids = require('./ids.js') class File { diff --git a/lib/app/site/models/files.js b/lib/app/files.js similarity index 98% rename from lib/app/site/models/files.js rename to lib/app/files.js index 99c76f0..96e5c78 100644 --- a/lib/app/site/models/files.js +++ b/lib/app/files.js @@ -1,7 +1,7 @@ 'use strict' // Dependencies -const paths = require('../utils/paths.js') +const paths = require('./paths.js') const File = require('./file.js') class Files diff --git a/lib/app/site/utils/ids.js b/lib/app/ids.js similarity index 100% rename from lib/app/site/utils/ids.js rename to lib/app/ids.js diff --git a/lib/app/index.js b/lib/app/index.js index e07d532..c638089 100644 --- a/lib/app/index.js +++ b/lib/app/index.js @@ -4,6 +4,11 @@ const ip = require('ip') const Site = require('./site') const Watcher = require('./watcher.js') +const Projects = require('./projects.js') +const socketIo = require('socket.io') +const util = require('util') +const colors = require('colors') +const opener = require('opener') /** * App class @@ -17,6 +22,12 @@ class App { this.setConfig() // this.setSite() + + this.socket = socketIo.listen() + + this.projects = new Projects({ socket: this.socket, debug: this.config.debug }) + this.project = this.projects.createProject(this.config.name) + this.setWatcher() } @@ -101,11 +112,7 @@ class App */ setSite() { - this.site = new Site({ - port: this.config.port, - domain: this.config.domain, - debug: this.config.debug - }) + this.site = new Site(this.config) } /** @@ -114,14 +121,69 @@ class App */ setWatcher() { - this.watcher = new Watcher({ - port: this.config.port, - domain: this.config.domain, - debug: this.config.debug, - maxFileSize: this.config.maxFileSize, - exclude: this.config.exclude, - name: this.config.name + this.watcher = new Watcher(this.config) + + const url = this.config.domain + '/project/' + this.project.slug + + console.log('server'.green.bold + ' - ' + url.cyan) + + // Open in browser + opener(url) + + // Debug + if(this.config.debug) + { + console.log(util.inspect(this.project.files.describe(), { depth: null, colors: true })) + } + + // Update file + this.watcher.on('update_file', (data) => + { + console.log(data) + this.project.files.createVersion(data.path, data.content) + + // Debug + if(this.config.debug) + { + console.log(util.inspect(this.project.files.describe(), { depth: null, colors: true })) + } }) + + // Create file + this.watcher.on('create_file', (data) => + { + this.project.files.create(data.path, data.content) + + // Debug + if(this.config.debug) + { + console.log(util.inspect(this.project.files.describe(), { depth: null, colors: true })) + } + }) + + // Delete file + this.watcher.on('delete_file', (data) => + { + this.project.files.delete(data.path) + + // Debug + if(this.config.debug) + { + console.log(util.inspect(this.project.files.describe(), { depth: null, colors: true })) + } + }) + + // // Disconnect + // this.watcher.on('disconnect', () => + // { + // this.projects.delete_project(this.project.slug) + + // // Debug + // if(this.config.debug) + // { + // console.log('socket app'.green.bold + ' - ' + 'disconnect'.cyan + ' - ' + socket.id.cyan) + // } + // }) } } diff --git a/lib/app/site/utils/paths.js b/lib/app/paths.js similarity index 100% rename from lib/app/site/utils/paths.js rename to lib/app/paths.js diff --git a/lib/app/site/models/project.js b/lib/app/project.js similarity index 100% rename from lib/app/site/models/project.js rename to lib/app/project.js diff --git a/lib/app/site/models/projects.js b/lib/app/projects.js similarity index 100% rename from lib/app/site/models/projects.js rename to lib/app/projects.js diff --git a/lib/app/site/controllers/index.js b/lib/app/site/controllers/index.js deleted file mode 100644 index a1949ec..0000000 --- a/lib/app/site/controllers/index.js +++ /dev/null @@ -1,19 +0,0 @@ -const express = require('express') -const router = express.Router() - -router.get('/', function(request, response) -{ - response.render('pages/index/projects.pug', {}) -}) - -router.get(/project\/(.+)/, function(request, response) -{ - response.render( - 'pages/index/project.pug', - { - projectSlug: request.params['0'] - } - ) -}) - -module.exports = router diff --git a/lib/app/site/index.js b/lib/app/site/index.js index 392e590..cbd7332 100644 --- a/lib/app/site/index.js +++ b/lib/app/site/index.js @@ -9,7 +9,7 @@ const colors = require('colors') const ip = require('ip') const util = require('util') const path = require('path') -const Projects = require('./models/projects.js') +const Projects = require('../projects.js') const fs = require('fs') const opener = require('opener') diff --git a/lib/app/site/models/event_emitter.js b/lib/app/site/models/event_emitter.js deleted file mode 100644 index 6a7a4ec..0000000 --- a/lib/app/site/models/event_emitter.js +++ /dev/null @@ -1,224 +0,0 @@ -'use strict' - -class EventEmitter -{ - /** - * Constructor - */ - constructor() - { - this.callbacks = {} - this.callbacks.base = {} - } - - /** - * On - */ - on(_names, callback) - { - const that = this - - // Errors - if(typeof _names === 'undefined' || _names === '') - { - console.warn('wrong names') - return false - } - - if(typeof callback === 'undefined') - { - console.warn('wrong callback') - return false - } - - // Resolve names - const names = this.resolveNames(names) - - // Each name - names.forEach(function(_name) - { - // Resolve name - const name = that.resolveName(_name) - - // Create namespace if not exist - if(!(that.callbacks[ name.namespace ] instanceof Object)) - that.callbacks[ name.namespace ] = {} - - // Create callback if not exist - if(!(that.callbacks[ name.namespace ][ name.value ] instanceof Array)) - that.callbacks[ name.namespace ][ name.value ] = [] - - // Add callback - that.callbacks[ name.namespace ][ name.value ].push(callback) - }) - - return this - } - - /** - * Off - */ - off(_names) - { - const that = this - - // Errors - if(typeof _names === 'undefined' || _names === '') - { - console.warn('wrong name') - return false - } - - // Resolve names - const names = this.resolveNames(_names) - - // Each name - names.forEach(function(_name) - { - // Resolve name - const name = that.resolveName(_name) - - // Remove namespace - if(name.namespace !== 'base' && name.value === '') - { - delete that.callbacks[ name.namespace ] - } - - // Remove specific callback in namespace - else - { - // Default - if(name.namespace === 'base') - { - // Try to remove from each namespace - for(const namespace in that.callbacks) - { - if(that.callbacks[ namespace ] instanceof Object && that.callbacks[ namespace ][ name.value ] instanceof Array) - { - delete that.callbacks[ namespace ][ name.value ] - - // Remove namespace if empty - if(Object.keys(that.callbacks[ namespace ]).length === 0) - delete that.callbacks[ namespace ] - } - } - } - - // Specified namespace - else if(that.callbacks[ name.namespace ] instanceof Object && that.callbacks[ name.namespace ][ name.value ] instanceof Array) - { - delete that.callbacks[ name.namespace ][ name.value ] - - // Remove namespace if empty - if(Object.keys(that.callbacks[ name.namespace ]).length === 0) - delete that.callbacks[ name.namespace ] - } - } - }) - - return this - } - - /** - * Trigger - */ - trigger(_name, _args) - { - // Errors - if(typeof _name === 'undefined' || _name === '') - { - console.warn('wrong name') - return false - } - - const that = this - let finalResult = null - let result = null - - // Default args - const args = !(args instanceof Array) ? [] : _args - - // Resolve names (should on have one event) - let name = this.resolveNames(_name) - - // Resolve name - name = this.resolveName(name[ 0 ]) - - // Default namespace - if(name.namespace === 'base') - { - // Try to find callback in each namespace - for(const namespace in that.callbacks) - { - if(that.callbacks[ namespace ] instanceof Object && that.callbacks[ namespace ][ name.value ] instanceof Array) - { - that.callbacks[ namespace ][ name.value ].forEach(function(callback) - { - result = callback.apply(that,args) - - if(typeof finalResult === 'undefined') - { - finalResult = result - } - }) - } - } - } - - // Specified namespace - else if(this.callbacks[ name.namespace ] instanceof Object) - { - if(name.value === '') - { - console.warn('wrong name') - return this - } - - that.callbacks[ name.namespace ][ name.value ].forEach(function(callback) - { - result = callback.apply(that, args) - - if(typeof finalResult === 'undefined') - finalResult = result - }) - } - - return finalResult - } - - /** - * Resolve names - */ - resolveNames(_names) - { - let names = _names - names = names.replace(/[^a-zA-Z0-9 ,\/.]/g, '') - names = names.replace(/[,\/]+/g, ' ') - names = names.split(' ') - - return names - } - - /** - * Resolve name - */ - resolveName(name) - { - const newName = {} - const parts = name.split('.') - - newName.original = name - newName.value = parts[ 0 ] - newName.namespace = 'base' // Base namespace - - // Specified namespace - if(parts.length > 1 && parts[ 1 ] !== '') - { - newName.namespace = parts[ 1 ] - } - - return newName - } -} - -module.exports = EventEmitter diff --git a/lib/app/site/views/pages/index/project.pug b/lib/app/site/views/pages/index/project.pug deleted file mode 100644 index 1f75620..0000000 --- a/lib/app/site/views/pages/index/project.pug +++ /dev/null @@ -1 +0,0 @@ -| Project \ No newline at end of file diff --git a/lib/app/site/views/pages/index/projects.pug b/lib/app/site/views/pages/index/projects.pug deleted file mode 100644 index c7e5bd0..0000000 --- a/lib/app/site/views/pages/index/projects.pug +++ /dev/null @@ -1 +0,0 @@ -| Projects \ No newline at end of file diff --git a/lib/app/watcher.js b/lib/app/watcher.js index 6b77ce0..3ae29bd 100644 --- a/lib/app/watcher.js +++ b/lib/app/watcher.js @@ -2,8 +2,6 @@ // Depedencies const chokidar = require('chokidar') -const ip = require('ip') -const socketIoClient = require('socket.io-client') const fs = require('fs') const mime = require('mime') const EventEmitter = require('../event-emitter.js') @@ -16,82 +14,28 @@ class Watcher extends EventEmitter /** * Constructor */ - constructor(_options) + constructor(_config) { super() - this.setOptions(_options) - this.setWatcher() - this.setSocket() + this.config = _config + + this.watch() } /** - * Set options + * Watch + * Listen to modifications on files and folders */ - setOptions(_options) - { - const options = typeof _options !== 'object' ? {} : _options - - // Defaults - if(typeof options.debug === 'undefined') - { - options.debug = false - } - - if(typeof options.port === 'undefined') - { - options.port = 1571 - } - - if(typeof options.domain === 'undefined') - { - options.domain = `http://${ip.address()}:${options.port}` - } - - if(typeof options.maxFileSize === 'undefined') - { - options.maxFileSize = 2000 - } - - // Save - this.options = options - } - - /** - * Set socket - * Connect to site - */ - setSocket() - { - // Set up - this.socket = socketIoClient(`${this.options.domain}/app`) - - // Connect event - this.socket.on('connect', () => - { - this.socket.emit('start_project', { name: this.options.name }) - - // Debug - if(this.options.debug) - { - console.log('connected'.green.bold) - } - }) - } - - /** - * Set watcher - * Listen to modifications on file and folders - */ - setWatcher() + watch() { // Create ignored regex const regexs = [] const Minimatch = require('minimatch').Minimatch - for(const _excludeKey in this.options.exclude) + for(const _excludeKey in this.config.exclude) { - const _exclude = this.options.exclude[ _excludeKey ] + const _exclude = this.config.exclude[_excludeKey] const minimatch = new Minimatch(_exclude, { dot: true }) let regex = '' + minimatch.makeRe() @@ -135,7 +79,7 @@ class Watcher extends EventEmitter fs.stat(_path, (error, stats) => { // Max file size - if(this.options.maxFileSize < stats.size) + if(this.config.maxFileSize < stats.size) { file.canRead = false } @@ -148,13 +92,13 @@ class Watcher extends EventEmitter file.content = data.toString() } - // Send - this.socket.emit('create_file', file) + // Trigger + this.trigger('create_file', [file]) }) }) // Debug - if(this.options.debug) + if(this.config.debug) { console.log('add:'.green.bold, relativePath) } @@ -181,7 +125,7 @@ class Watcher extends EventEmitter fs.stat(_path, (error, stats) => { // Test max file size - if(this.options.maxFileSize < stats.size) + if(this.config.maxFileSize < stats.size) { file.canRead = false } @@ -194,13 +138,13 @@ class Watcher extends EventEmitter file.content = data.toString() } - // Send - this.socket.emit('update_file', file) + // Trigger + this.trigger('update_file', [file]) }) }) // Debug - if(this.options.debug) + if(this.config.debug) { console.log('change:'.green.bold, relativePath) } @@ -212,11 +156,11 @@ class Watcher extends EventEmitter // Set up const relativePath = _path.replace(process.cwd(), '.') - // Send - this.socket.emit('delete_file', { path: relativePath }) + // Trigger + this.trigger('delete_file', [relativePath]) // Debug - if(this.options.debug) + if(this.config.debug) { console.log('unlink:'.green.bold, relativePath) } @@ -228,11 +172,11 @@ class Watcher extends EventEmitter // Set up const relativePath = _path.replace(process.cwd(), '.') - // Send - this.socket.emit('create_folder', { path: relativePath }) + // Trigger + this.trigger('create_folder', [{ path: relativePath }]) // Debug - if(this.options.debug) + if(this.config.debug) { console.log('addDir:'.green.bold, relativePath) } @@ -244,11 +188,11 @@ class Watcher extends EventEmitter // Set up const relativePath = _path.replace(process.cwd(), '.') - // Send - this.socket.emit('delete_folder', { path: relativePath }) + // Trigger + this.trigger('delete_folder', [{ path: relativePath }]) // Debug - if(this.options.debug) + if(this.config.debug) { console.log('unlinkDir:'.green.bold, relativePath) } diff --git a/lib/event-emitter.js b/lib/event-emitter.js index 6a7a4ec..f9491bf 100644 --- a/lib/event-emitter.js +++ b/lib/event-emitter.js @@ -32,7 +32,7 @@ class EventEmitter } // Resolve names - const names = this.resolveNames(names) + const names = this.resolveNames(_names) // Each name names.forEach(function(_name) @@ -136,7 +136,7 @@ class EventEmitter let result = null // Default args - const args = !(args instanceof Array) ? [] : _args + const args = !(_args instanceof Array) ? [] : _args // Resolve names (should on have one event) let name = this.resolveNames(_name) @@ -154,7 +154,7 @@ class EventEmitter { that.callbacks[ namespace ][ name.value ].forEach(function(callback) { - result = callback.apply(that,args) + result = callback.apply(that, args) if(typeof finalResult === 'undefined') { diff --git a/test/demo-folder/soidjf b/test/demo-folder/soidjf new file mode 100644 index 0000000..2c1bbbb --- /dev/null +++ b/test/demo-folder/soidjf @@ -0,0 +1 @@ +dfsdf \ No newline at end of file diff --git a/test/demo-folder/testouille b/test/demo-folder/testouille new file mode 100644 index 0000000..cb52772 --- /dev/null +++ b/test/demo-folder/testouille @@ -0,0 +1,2 @@ +wcwxcsfazeazes +sdfsdfoij \ No newline at end of file