├── .gitignore ├── .npmignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── bin ├── basel-crud.js ├── basel-database.js └── basel-init.js ├── images ├── basel.fw.png └── basel_shield.fw.png ├── lib ├── basel.config.js ├── crud.js ├── database.js ├── install.js ├── utils.js └── wizard.js ├── package.json └── templates ├── controller.js └── crud.html /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 18 | .grunt 19 | 20 | # node-waf configuration 21 | .lock-wscript 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | 26 | # Dependency directory 27 | node_modules 28 | 29 | # Optional npm cache directory 30 | .npm 31 | 32 | # Optional REPL history 33 | .node_repl_history 34 | 35 | #Test folter 36 | test -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | test -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | This change log is started in 0.0.9; 3 | 4 | ## 0.1.1 (2016-05-30) 5 | - Deleting crud 6 | 7 | ## 0.1.0 (2016-05-12) 8 | - Save basel.json data in package.json 9 | - Release 10 | 11 | ## 0.0.17 (2016-04-29) 12 | - Adapt to accept other themes 13 | 14 | ## 0.0.16 (2016-04-27) 15 | - Fixes main path 16 | 17 | ## 0.0.15 (2016-04-25) 18 | - Create model folder if doesn't exists - REview 19 | 20 | ## 0.0.14 (2016-04-25) 21 | - Create model folder if doesn't exists 22 | 23 | ## 0.0.13 (2016-04-22) 24 | - Use URL git to clone base repositories. 25 | - Show error on create table, if necessary. 26 | - Use CRUD name in view, controller and route name. 27 | 28 | ## 0.0.12 (2016-04-21) 29 | - List CRUDS with ``` basel-crud -l ``` 30 | - Delete CRUD by id with ``` base-crud -d ``` 31 | 32 | ## 0.0.11 (2016-04-21) 33 | - Create table when create CRUD 34 | 35 | ## 0.0.10 (2016-04-20) 36 | - Change creating tables 37 | - Create utils module 38 | - Change README.md 39 | 40 | ## 0.0.9 (2016-04-19) 41 | - Creating controller in basel-crud 42 | - Changing index in basel-crud 43 | - Review in table creating - basel-database 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Clube dos Geeks 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 |

Framework for Bootstrap, AngularJS, SQLite, Electron

3 | ## [Documentation](http://baseljs.github.io/#/) 4 | 5 | ## Usage 6 | Install 7 | ```shell 8 | npm install -g basel 9 | ``` 10 | 11 | Create App 12 | ```shell 13 | basel-init myApp 14 | ``` 15 | 16 | Install dependencies 17 | ```shell 18 | cd myApp && npm install 19 | ``` 20 | 21 | Run 22 | ```shell 23 | npm start 24 | ``` 25 | 26 | ## Database 27 | To create a new table in the database of your BASEL app. 28 | ```shell 29 | basel-database --table USERS --columns "id:INTEGER, name:TEXT" --pk id 30 | ``` 31 | And manipulate the database. 32 | 33 | ### Options 34 | ```shel 35 | -h, --help output usage information 36 | -p, --password Data base encripted passowrd 37 | -a, --algorithm Data base encripted algorithm 38 | -s, --sql Sql to run 39 | -t, --table Create database table 40 | -c, --columns Database table columns. Ex: "id:INTEGER, name:TEXT" 41 | -p, --pk Database table primary key 42 | -r, --references Refences. Ex: "id":"table.id_table" 43 | -i, --incremental incremental columns. Ex: id or "id, number, ..." 44 | ``` 45 | 46 | #### Example: 47 | ```shell 48 | basel-database --table USERS --columns "id:INTEGER, name:CHAR(100), email:TEXT, profile:INTEGER" --pk id --incremental id --references "profile:profiles.id" 49 | ``` 50 | Mean: 51 | ```sql 52 | CREATE table USERS( 53 | id INTEGER PRIMARY KEY AUTOINCREMENT, 54 | name CHAR (100), 55 | email TEXT, 56 | profile INTEGER REFERENCES profiles(id) 57 | ); 58 | ``` 59 | 60 | ## CRUD - Creating 61 | To create CRUD from database tables. 62 | ```shell 63 | basel-crud users --table USERS 64 | ``` 65 | ### Options 66 | ```shell 67 | -h, --help output usage information 68 | -t, --table
Database Table 69 | -n, --columns For new tables. Table columns. Ex: "id:INTEGER, name:TEXT" 70 | -p, --pk Primary key of new table 71 | -f, --references Refences of new table. Ex: "profile:profiles.id" 72 | -i, --incremental incremental columns. Ex: id or "id, number, ..." 73 | -b, --database Database 74 | -c, --controller Controller name 75 | -v, --view View name (.html) 76 | -r, --route Route (Ex.: persons) 77 | -m, --menu Show in main menu (1 - Yes, 0 - No) Default 1 78 | -d, --delete To delete CRUD by ID 79 | -l, --list To list CRUDS 80 | ``` 81 | 82 | #### Examples 83 | ```shell 84 | basel-crud users --table USERS -c userController -v user -r users 85 | ``` 86 | Create a CRUD on Controller and view based in table USERS. 87 | 88 | ### Create CRUD and Table 89 | you can create the CRUD and at the same time the table. Inform the table columns using the short -n or --columns "id:INTEGER, name:TEXT, ... ". 90 | ```shell 91 | basel-crud users --table USERS -n "id:INTEGER, name:TEXT" 92 | ``` 93 | 94 | ## Help 95 | 96 | ### Init 97 | ```shell 98 | basel-init --help 99 | ``` 100 | 101 | ### Database 102 | ```shell 103 | basel-database --help 104 | ``` 105 | ### CRUD 106 | ```shell 107 | basel-crud --help 108 | ``` 109 | -------------------------------------------------------------------------------- /bin/basel-crud.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var basel = require('../lib/basel.config.js'), 3 | inquirer = require('inquirer'), 4 | program = require('commander'), 5 | crud = require('../lib/crud.js'), 6 | utils = require('../lib/utils'), 7 | _ = require('lodash'); 8 | 9 | program 10 | .description('Create a BASEL crud in the current app') 11 | .option('-t, --table
', 'Database Table') 12 | .option('-n, --columns ', 'For new tables. Table columns. Ex: "id:INTEGER, name:TEXT"') 13 | .option('-p, --pk ', 'Primary key of new table') 14 | .option('-f, --references ', 'Refences of new table. Ex: "profile:profiles.id"') 15 | .option('-i, --incremental ', 'incremental columns. Ex: id or "id, number, ..." ') 16 | .option('-c, --controller ', 'Controller name') 17 | .option('-v, --view ', 'View name (*.html)') 18 | .option('-r, --route ', 'Route (Ex.: persons)') 19 | .option('-m, --menu ', 'Show in main menu (1 - Yes, 0 - No) Default 1') 20 | 21 | .option('-l, --list ', 'List cruds') 22 | .option('-d, --delete ', 'Delete CRUD by id') 23 | .parse(process.argv); 24 | 25 | 26 | basel.config.name_ = program.args.length ? program.args[0] : 'basel'; 27 | basel.config.table = program.table; 28 | basel.config.columns = program.columns; 29 | basel.config.primary = program.primary || program.pk; 30 | basel.config.references = program.references; 31 | basel.config.incremental = program.incremental; 32 | basel.config.database = program.database || basel.config.database; 33 | basel.config.controller = program.controller; 34 | basel.config.view = program.view; 35 | basel.config.route = program.route; 36 | basel.config.show_menu = program.menu || 1; 37 | 38 | basel.config.list = program.list; 39 | basel.config.id = program.delete; 40 | 41 | 42 | if(basel.error){ 43 | console.log(basel.error) 44 | }else{ 45 | if(basel.config.list){ 46 | crud.list(basel.config) 47 | } 48 | else if(basel.config.id){ 49 | // delete crud 50 | var options = basel.config; 51 | console.log("Your files of view and controller will be deleted!"); 52 | var questions =[ 53 | { 54 | type:'input', 55 | name:'yes_no', 56 | message:'Are you sure (y/n) ?', 57 | default:'y' 58 | } 59 | ]; 60 | 61 | inquirer.prompt(questions, function(results) { 62 | _.assign(options, results); 63 | crud.delete(options); 64 | }); 65 | } 66 | else{ 67 | wizard(basel.config); 68 | } 69 | } 70 | 71 | function wizard (options) { 72 | var questions = []; 73 | var word = shortName(options.name_); 74 | options.controller = options.controller || word+"Controller"; 75 | options.view = options.view || word+".html"; 76 | 77 | if(!options.table){ 78 | questions.push({ 79 | type: 'input', 80 | name: 'table', 81 | message: 'What is the database table?' 82 | }); 83 | } 84 | 85 | if(!options.route){ 86 | questions.push({ 87 | type: 'input', 88 | name: 'route', 89 | message: 'What is the route way?', 90 | default: word 91 | }); 92 | } 93 | 94 | if(options.columns){ 95 | if(!options.primary){ 96 | var cols = utils.json(options.columns); 97 | questions.push({ 98 | type: 'input', 99 | name: 'primary', 100 | message: 'What is the primary key?', 101 | default: Object.keys(cols)[0] 102 | }); 103 | } 104 | if(!options.incremental){ 105 | questions.push({ 106 | type: 'input', 107 | name: 'incremental', 108 | message: 'Do you have any incremental columns?' 109 | }); 110 | } 111 | } 112 | 113 | inquirer.prompt(questions, function(results) { 114 | _.assign(options, results); 115 | crud.init(options); 116 | }); 117 | } 118 | 119 | 120 | function shortName(str){ 121 | return removerAcentos(str).toLowerCase().replace(/ /g,''); 122 | } 123 | 124 | /** 125 | * Remove acentos de caracteres 126 | * @param {String} stringComAcento [string que contem os acentos] 127 | * @return {String} [string sem acentos] 128 | */ 129 | function removerAcentos( newStringComAcento ) { 130 | var string = newStringComAcento; 131 | var mapaAcentosHex = { 132 | a : /[\xE0-\xE6]/g, 133 | e : /[\xE8-\xEB]/g, 134 | i : /[\xEC-\xEF]/g, 135 | o : /[\xF2-\xF6]/g, 136 | u : /[\xF9-\xFC]/g, 137 | c : /\xE7/g, 138 | n : /\xF1/g 139 | }; 140 | 141 | for ( var letra in mapaAcentosHex ) { 142 | var expressaoRegular = mapaAcentosHex[letra]; 143 | string = string.replace( expressaoRegular, letra ); 144 | } 145 | 146 | return string; 147 | } 148 | -------------------------------------------------------------------------------- /bin/basel-database.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var basel = require('../lib/basel.config.js'), 3 | database = require('../lib/database.js'), 4 | inquirer = require('inquirer'), 5 | program = require('commander'), 6 | utils = require('../lib/utils') 7 | _ = require('lodash'); 8 | 9 | program 10 | .description('Create and access the database of a BASEL Application') 11 | .option('-p, --password ', 'Data base encripted passowrd') 12 | .option('-a, --algorithm ', 'Data base encripted algorithm') 13 | .option('-s, --sql ', 'Sql to run') 14 | .option('-t, --table
', 'Create database table') 15 | .option('-c, --columns ', 'Database table columns. Ex: "id:INTEGER, name:TEXT"') 16 | .option('-p, --pk ', 'Primary key of new table') 17 | .option('-r, --references ', 'Refences. Ex: "profile:profiles.id"') 18 | .option('-i, --incremental ', 'incremental columns. Ex: id or "id, number, ..." ') 19 | .parse(process.argv); 20 | 21 | basel.config.database = program.args.length ? program.args[0] : basel.config.database; 22 | basel.config.password = program.password; 23 | basel.config.algorithm = program.algorithm; 24 | 25 | basel.config.sql = program.sql; 26 | basel.config.table = program.table; 27 | basel.config.columns = program.columns; 28 | basel.config.primary = program.primary; 29 | basel.config.references = program.references; 30 | basel.config.incremental = program.incremental; 31 | 32 | if(program.args.length){ 33 | basel.config.connect = true; 34 | } 35 | 36 | if(basel.error){ 37 | console.log(basel.error) 38 | }else{ 39 | // console.log(basel.config) 40 | wizard(basel.config); 41 | } 42 | 43 | function required(value) { 44 | return !!value.trim() || 'Required'; 45 | } 46 | 47 | function wizard (options) { 48 | var questions = []; 49 | 50 | if(options.cipher && !options.password){ 51 | questions.push({ 52 | type: 'input', 53 | name: 'password', 54 | message: 'What is the sqlite-cipher password?', 55 | validate: required 56 | }); 57 | } 58 | 59 | if(options.cipher && !options.algorithm){ 60 | questions.push({ 61 | type: 'input', 62 | name: 'algorithm', 63 | message: 'What is the sqlite-cipher algorithm?', 64 | validate: required, 65 | default: 'aes-256-ctr' 66 | }); 67 | } 68 | 69 | if(options.table){ 70 | if(!options.columns){ 71 | questions.push({ 72 | type: 'input', 73 | name: 'columns', 74 | message: 'You need to inform the columns of your table', 75 | validate: required, 76 | default: "{id: 'INTEGER',name:'TEXT'}" 77 | }); 78 | } 79 | if(!options.primary){ 80 | var cols = utils.json(options.columns); 81 | questions.push({ 82 | type: 'input', 83 | name: 'primary', 84 | message: 'What is the primary key?', 85 | validate: required, 86 | default: Object.keys(cols)[0] 87 | }); 88 | } 89 | if(!options.incremental){ 90 | questions.push({ 91 | type: 'input', 92 | name: 'incremental', 93 | message: 'Do you have any incremental columns?', 94 | validate: required, 95 | }); 96 | } 97 | } 98 | 99 | inquirer.prompt(questions, function(results) { 100 | _.assign(options, results); 101 | database.wizard(options); 102 | }); 103 | } 104 | -------------------------------------------------------------------------------- /bin/basel-init.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var wizard = require('../lib/wizard'), 3 | program = require('commander'); 4 | 5 | program 6 | .description('Create a BASEL application in the current working directory') 7 | .option('-d, --database ', 'Data base name') 8 | .option('-c, --cipher ', 'Data base encripted') 9 | .option('-p, --passowrd ', 'Data base encripted passowrd') 10 | .option('-a, --algorithm ', 'Data base encriptation algorithm') 11 | .option('-t, --title ', 'Application title') 12 | .option('-e, --description <description>', 'Application description') 13 | .option('-u, --url <url>', 'URL of Git repository') 14 | .option('-b, --base <base>', 'Base app for BASEL') 15 | .parse(process.argv); 16 | 17 | var options = { 18 | name: program.args.length ? program.args[0] : 'basel', 19 | database: program.database || 'database', 20 | title: program.title, 21 | type: program.type || 'simple', 22 | description: program.description || 'BASEL Application', 23 | cipher: program.cipher, 24 | passowrd: program.passowrd, 25 | algorithm: program.algorithm, 26 | url: program.url, 27 | base: program.base 28 | }; 29 | 30 | wizard(options); 31 | -------------------------------------------------------------------------------- /images/basel.fw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baseljs/basel/2777d17b6c18d71f0b2e3207ff0e910d47add7cb/images/basel.fw.png -------------------------------------------------------------------------------- /images/basel_shield.fw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baseljs/basel/2777d17b6c18d71f0b2e3207ff0e910d47add7cb/images/basel_shield.fw.png -------------------------------------------------------------------------------- /lib/basel.config.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'), 2 | path = require('path'); 3 | 4 | var jsonFile = path.join(process.cwd(),'basel.json'); 5 | 6 | if(fs.existsSync(jsonFile)){ 7 | exports.config = JSON.parse(fs.readFileSync(jsonFile)); 8 | }else{ 9 | exports.erro = "This directory is not a BASEL app"; 10 | } -------------------------------------------------------------------------------- /lib/crud.js: -------------------------------------------------------------------------------- 1 | var jsdom = require("jsdom/lib/old-api.js"); 2 | var fs = require("fs"); 3 | var _database = require('./database.js'); 4 | var series = require('async-series'); 5 | var path = require('path'); 6 | 7 | exports.init = function (options) { 8 | options.db = _database.init(options); 9 | if(options.columns){ 10 | _database.createTable(options); 11 | } 12 | series([ 13 | function(done) { 14 | view(options,done); 15 | }, 16 | function(done) { 17 | controller(options,done) 18 | }, 19 | function(done) { 20 | index(options) 21 | } 22 | ], function(err) { 23 | console.log(err.message) // "another thing" 24 | }); 25 | } 26 | 27 | exports.list = function(options){ 28 | options.db = _database.init(options); 29 | var list = options.db.run("SELECT * FROM crud WHERE ativo = 1"); 30 | console.log(list); 31 | options.db.close(); 32 | } 33 | 34 | exports.delete = function(options){ 35 | if(options.yes_no == 'y' || options.yes_no == 'Y'){ 36 | var db = _database.init(options); 37 | var crud = db.run("SELECT * FROM crud WHERE id=?",[options.id]); 38 | if(crud.length>0){ 39 | db.update('crud',{ativo:0},{id:options.id}); 40 | crud = crud[0]; 41 | var viewFile = path.join(process.cwd(),'views',crud.view); 42 | var controllerFile = path.join(process.cwd(),'controllers',crud.controller+'.js'); 43 | fs.unlink(viewFile,function(err){ 44 | if(err){ 45 | console.error(err) 46 | }else{ 47 | console.log("View file deleted"); 48 | } 49 | }); 50 | fs.unlink(controllerFile,function(err){ 51 | if(err){ 52 | console.error(err) 53 | }else{ 54 | console.log("Controller file deleted"); 55 | } 56 | }); 57 | 58 | fs.readFile(path.join(process.cwd(),'index.html'), 'utf8', function(error, data) { 59 | jsdom.env(data, function (errors, window) { 60 | var $ = require('jquery')(window); 61 | $('script[src="controllers/'+crud.controller+'.js"]').remove() 62 | if( ! $('script[src="controllers/'+crud.controller+'.js"]').length){ 63 | console.log("Reference removed from index.html"); 64 | db.delete('crud',{id:options.id}, function(res){ 65 | console.log(); 66 | console.log("CRUD deleted") 67 | }); 68 | } 69 | fs.writeFile(path.join(process.cwd(),'index.html'), window.document.documentElement.outerHTML, function (error){ 70 | if (error) throw error; 71 | console.log(); 72 | }); 73 | 74 | }); 75 | }); 76 | 77 | 78 | 79 | }else{ 80 | console.log("ID "+options.id+" not found!") 81 | } 82 | db.close(); 83 | } 84 | } 85 | 86 | var routeExists = function(options){ 87 | var res = options.db.run("SELECT * FROM crud WHERE route = ? ",[options.route]); 88 | return res.length>0; 89 | } 90 | 91 | function view(options, done){ 92 | console.log("Creating view..."); 93 | if(routeExists(options)){ 94 | options.route = options.route+"_1"; 95 | console.log("Route renamed for "+options.route); 96 | } 97 | var db = options.db; 98 | var fields = db.run('PRAGMA table_info(?)',[options.table]); 99 | var template = path.join(process.cwd(),'templates','crud.html'); 100 | if(!fs.existsSync(template)){ 101 | template = path.join(__dirname,'templates','crud.html'); 102 | } 103 | fs.readFile(template, 'utf8', function(error, data) { 104 | jsdom.env(data, function (errors, window) { 105 | var $ = require('jquery')(window); 106 | 107 | $('.basel-controller').attr('ng-controller',options.controller); 108 | $('.modal-title').text(options.name_); 109 | 110 | var headTable = $('.basel-table-head').append($('<tr/>')).find('tr'); 111 | var bodyTable = $('.basel-table-body').append($('<tr/>').attr('dir-paginate','item in items | filter: search | itemsPerPage: 10')).find('tr'); 112 | var form = $('.basel-form'); 113 | 114 | for(var i = 0 ; i < fields.length ; i++){ 115 | var field = fields[i]; 116 | headTable.append('<th>'+field.name+'</th>'); 117 | bodyTable.append('<td>{{item.'+field.name+'}}</td>'); 118 | 119 | var input = $('<input/>').attr({ 120 | type:'text', 121 | class:'form-control', 122 | "ng-model":"form."+field.name 123 | }); 124 | 125 | form.append($('<div/>', { 126 | class:'form-group' 127 | }).append($('<label/>').text(field.name)).append(input)); 128 | } 129 | 130 | headTable.append('<th></th>'); 131 | 132 | var btnEdit = $('<button>').attr({ 133 | class:"btn btn-info btn-xs", 134 | "ng-click":'edit(item)' 135 | }).html('<span class="glyphicon glyphicon-pencil"></span> Edit'); 136 | 137 | var btnDelete = $('<button>').attr({ 138 | class:"btn btn-danger btn-xs", 139 | "ng-click":'delete(item)' 140 | }).html('<span class="glyphicon glyphicon-trash"></span> Delete'); 141 | 142 | bodyTable.append($('<td/>').append(btnEdit).append(btnDelete)); 143 | 144 | var data = $('div').first().parent().html(); 145 | data = data.split('CONTROLLER_NAME').join(options.controller); 146 | 147 | fs.writeFile(path.join(process.cwd(),'views',options.view), data, function (error){ 148 | if (error) throw error; 149 | console.log("View created!") 150 | done(); 151 | }); 152 | }); 153 | }); 154 | } 155 | 156 | function controller(options, done){ 157 | console.log("Creating controller..."); 158 | var db = options.db; 159 | var fields = db.run('PRAGMA table_info(?)',[options.table]); 160 | var template = path.join(process.cwd(),'templates','controller.js'); 161 | if(!fs.existsSync(template)){ 162 | template = path.join(__dirname,'templates','controller.js'); 163 | } 164 | fs.readFile(template, 'utf8', function(error, data) { 165 | 166 | data = data.split('CONTROLLER_NAME').join(options.controller); 167 | data = data.split('TABLE_NAME').join(options.table); 168 | 169 | for(var i = 0 ; i < fields.length ; i++){ 170 | if(fields[i].pk == 1){ 171 | data = data.split('PRIMARY_KEY').join(fields[i].name); 172 | break; 173 | } 174 | } 175 | 176 | fs.writeFile(path.join(process.cwd(),'controllers',options.controller+".js"), data, function (error){ 177 | if (error) throw error; 178 | console.log("Controller created!") 179 | done(); 180 | }); 181 | }); 182 | } 183 | 184 | function index(options){ 185 | var db = options.db; 186 | fs.readFile(path.join(process.cwd(),'index.html'), 'utf8', function(error, data) { 187 | jsdom.env(data, function (errors, window) { 188 | var $ = require('jquery')(window); 189 | if( ! $('script[src="controllers/'+options.controller+'.js"]').length){ 190 | if($('script[src="controllers/mainController.js"]').length > 0){ 191 | $( '<script src="controllers/'+options.controller+'.js" />' ).insertAfter( $('script[src="controllers/mainController.js"]') ); 192 | }else{ 193 | $('head').append('<script src="controllers/'+options.controller+'.js" />') 194 | } 195 | } 196 | db.insert('crud',{ 197 | name: options.name_, 198 | view: options.view, 199 | controller: options.controller, 200 | table_: options.table, 201 | route: options.route, 202 | show_menu: options.show_menu 203 | }); 204 | fs.writeFile(path.join(process.cwd(),'index.html'), window.document.documentElement.outerHTML, function (error){ 205 | if (error) throw error; 206 | console.log(); 207 | console.log("CRUD created!"); 208 | db.close(); 209 | }); 210 | 211 | }); 212 | }); 213 | } 214 | -------------------------------------------------------------------------------- /lib/database.js: -------------------------------------------------------------------------------- 1 | var shell = require('shelljs'); 2 | var path = require('path'); 3 | var fs = require('fs'); 4 | var chalk = require('chalk'); 5 | var series = require('async-series'); 6 | var utils = require('../lib/utils'); 7 | var database; 8 | 9 | exports.init = function (options, done) { 10 | if(done){ 11 | var databaseFile = (options.database.split('\\')).length > 1 ? options.database : path.join(process.cwd(),options.name,'model', options.database+'.db'); 12 | var dir = path.join(process.cwd(),options.name,'model'); 13 | if (!fs.existsSync(dir)){ 14 | fs.mkdirSync(dir); 15 | } 16 | }else{ 17 | var databaseFile = (options.database.split('\\')).length > 1 ? options.database : path.join(process.cwd(),'model', options.database+'.db'); 18 | } 19 | 20 | if(options.cipher){ 21 | var sqlite_cipher = require('sqlite-cipher'); 22 | sqlite_cipher.connect(databaseFile, options.password, options.algorithm); 23 | database = sqlite_cipher; 24 | }else{ 25 | var sqlite_sync = require('sqlite-sync'); 26 | sqlite_sync.connect(databaseFile); 27 | database = sqlite_sync; 28 | } 29 | console.log("Connected in database"); 30 | if(done){ 31 | database.run('CREATE TABLE crud (id INTEGER PRIMARY KEY AUTOINCREMENT, name CHAR (50), [view] CHAR (50), controller CHAR (50), table_ CHAR (50), route CHAR (50), show_menu INT DEFAULT (1), ativo INT DEFAULT (1) )'); 32 | var res = database.run('SELECT * FROM crud WHERE name="Example"'); 33 | if(res.length == 0){ 34 | database.run("INSERT INTO crud (name, view, controller, route) VALUES ('Example', 'example.html', 'exampleController', 'example')"); 35 | } 36 | done(options) 37 | } 38 | return database; 39 | } 40 | 41 | exports.wizard = function(options){ 42 | options.database = (options.database.split('\\')).length > 1 ? options.database : path.join(process.cwd(),'model',options.database+'.db'); 43 | if(options.connect){ 44 | this.init(options); 45 | }else if(!database){ 46 | this.init(options); 47 | } 48 | if(options.sql){ 49 | console.log(database.run(options.sql)); 50 | } 51 | if(options.table){ 52 | createTable(options); 53 | } 54 | } 55 | 56 | function createTable(options){ 57 | var colunms = utils.json(options.columns); 58 | var references = (options.references) ? utils.json(options.references) : []; 59 | var incremental = (options.incremental) ? options.incremental.split(',') : []; 60 | var colSql = []; 61 | 62 | var keys = Object.keys(colunms); 63 | for(var i = 0 ; i < keys.length ; i++){ 64 | var sql = keys[i]+" "+colunms[keys[i]]; 65 | if(keys[i] == options.primary){ 66 | sql += " PRIMARY KEY"; 67 | } 68 | for(j in incremental){ 69 | if(incremental[j] == keys[i]){ 70 | sql += " AUTOINCREMENT"; 71 | } 72 | } 73 | if(references[keys[i]]){ 74 | var parts = references[keys[i]].split('.'); 75 | sql += " REFERENCES "+parts[0]+" ("+parts[1]+")"; 76 | } 77 | colSql.push(sql); 78 | } 79 | 80 | var sql = "CREATE TABLE "+options.table+"("+colSql.join(',')+")"; 81 | console.log(sql) 82 | var res = database.run(sql); 83 | if(!res){ 84 | throw "An error occurred while creating a table, check the types of data, and try again." 85 | }else{ 86 | console.log("Table "+options.table+" created in database: "+options.database); 87 | } 88 | } 89 | 90 | exports.createTable = createTable; -------------------------------------------------------------------------------- /lib/install.js: -------------------------------------------------------------------------------- 1 | var shell = require('shelljs'); 2 | var path = require('path'); 3 | var fs = require('fs'); 4 | var chalk = require('chalk'); 5 | var series = require('async-series'); 6 | var database = require('./database'); 7 | exports.init = function(options) { 8 | series([ 9 | function(done) { 10 | clone(options,done); 11 | }, 12 | function(done) { 13 | changeJson(options,done) 14 | }, 15 | function(done) { 16 | renameRemote(options) 17 | } 18 | ], function(err) { 19 | console.log(err.message) // "another thing" 20 | }) 21 | } 22 | 23 | var clone = function(options, done){ 24 | var url = "https://github.com/baseljs/basel-app.git"; 25 | if(options.url){ 26 | url = options.url; 27 | }else if(options.base){ 28 | var valids_base = ['tabs']; 29 | if(valids_base.indexOf(options.base) >= 0){ 30 | url = "https://github.com/baseljs/basel-app-"+options.base+".git"; 31 | }else{ 32 | throw "This base is not valid! The valids are: "+valids_base.join(','); 33 | } 34 | } 35 | var gitCmd = 'git clone '+url+' "'+options.name+'"'; 36 | console.log('Cloning into destination folder:' +options.name); 37 | console.log(gitCmd); 38 | shell.exec(gitCmd , function(status, output) { 39 | if (status) { 40 | console.log(output); 41 | } 42 | console.log(); 43 | done() 44 | }); 45 | } 46 | 47 | var changeJson = function(options, done){ 48 | var filename = path.join(process.cwd(), options.name,'package.json'); 49 | var json = JSON.parse(fs.readFileSync(filename)); 50 | json.name = options.name; 51 | json.titel = options.title; 52 | fs.writeFileSync(filename, JSON.stringify(json)); 53 | done() 54 | } 55 | 56 | var renameRemote = function(options, done){ 57 | shell.exec('cd '+ options.name + ' && git remote rename origin upstream', function (status, error) { 58 | if (!status) { 59 | console.log(' Added the "remote" upstream origin'); 60 | console.log(); 61 | console.log(); 62 | console.log('#############################################'); 63 | console.log(); 64 | console.log(chalk.green.bold(' Congratulations you have basel-io installed.')); 65 | console.log(); 66 | database.init(options,createJson); 67 | } else { 68 | console.log(error); 69 | } 70 | }); 71 | } 72 | 73 | var createJson = function(options){ 74 | fs.readFile(path.join(process.cwd(),options.name,'package.json'), function(err, data){ 75 | data = JSON.parse(data); 76 | if(!err){ 77 | for(var key in options){ 78 | data[key] = options[key]; 79 | } 80 | fs.writeFileSync(path.join(process.cwd(),options.name,'package.json') , JSON.stringify(data, null, 4)); 81 | } 82 | }) 83 | fs.writeFileSync(path.join(process.cwd(),options.name,'basel.json') , JSON.stringify(options, null, 4)); 84 | } -------------------------------------------------------------------------------- /lib/utils.js: -------------------------------------------------------------------------------- 1 | exports.json = function (str) { 2 | var object = {}; 3 | var parts = str.split(','); 4 | for(i in parts){ 5 | var partsItem = parts[i].split(':'); 6 | object[partsItem[0].trim()] = partsItem[1].trim(); 7 | } 8 | return object; 9 | } -------------------------------------------------------------------------------- /lib/wizard.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var inquirer = require('inquirer'), 4 | install = require('./install'), 5 | _ = require('lodash'); 6 | 7 | module.exports = function(options) { 8 | function required(value) { 9 | return !!value.trim() || 'Required'; 10 | } 11 | var questions = [{ 12 | type: 'input', 13 | name: 'name', 14 | message: 'What would you name your basel app?', 15 | default: options.name, 16 | validate: required 17 | }]; 18 | 19 | if(!options.title){ 20 | questions.push({ 21 | type: 'input', 22 | name: 'title', 23 | message: 'What will be the title of your application window?', 24 | default: options.name, 25 | validate: required 26 | }); 27 | } 28 | 29 | if(options.cipher){ 30 | if(!options.password){ 31 | questions.push({ 32 | type: 'input', 33 | name: 'password', 34 | message: 'What is the sqlite-cipher password?', 35 | validate: required 36 | }); 37 | } 38 | if(!options.algorithm){ 39 | questions.push({ 40 | type: 'input', 41 | name: 'algorithm', 42 | message: 'What is the sqlite-cipher algorithm?', 43 | validate: required, 44 | default: 'aes-256-ctr' 45 | }); 46 | } 47 | } 48 | 49 | inquirer.prompt(questions, function(results) { 50 | _.assign(options, results); 51 | install.init(options); 52 | }); 53 | 54 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "basel", 3 | "version": "0.1.2", 4 | "description": "Framework for Bootstrap, AngularJS, SQLite, Electron", 5 | "author": "Jayr Alencar <http://github.com/jayralencar>", 6 | "readmeFilename": "README.md" , 7 | "keywords": [ 8 | "basel", 9 | "basel-io", 10 | "desktop", 11 | "electron", 12 | "bootstrap", 13 | "angularjs" 14 | ], 15 | "tags": [ 16 | "basel", 17 | "basel-io", 18 | "desktop", 19 | "electron", 20 | "bootstrap", 21 | "angularjs" 22 | ], 23 | "license": "MIT", 24 | "bin": { 25 | "basel-init": "./bin/basel-init.js", 26 | "basel-database": "./bin/basel-database.js", 27 | "basel-crud": "./bin/basel-crud.js" 28 | }, 29 | "main" : "./lib/basel", 30 | "preferGlobal": "true", 31 | "dependencies": { 32 | "chalk": "^0.5.1", 33 | "commander": "^2.4.0", 34 | "shelljs": "^0.3.0", 35 | "lodash": "^2.4.1", 36 | "async-series":"latest", 37 | "inquirer": "^0.8.0", 38 | "crypto": "latest", 39 | "sqlite-sync":"latest", 40 | "sqlite-cipher":"latest", 41 | "jsdom":"1.1.0", 42 | "jquery":"latest" 43 | }, 44 | "engines": { 45 | "node": ">=0.8.0" 46 | }, 47 | "repository": { 48 | "type": "git", 49 | "url": "git+https://github.com/ClubeDosGeeksCoding/basel.git" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /templates/controller.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | app.controller("CONTROLLER_NAME", function($scope, $location){ 3 | 4 | $scope.table_name = "TABLE_NAME"; 5 | $scope.primary_key = "PRIMARY_KEY"; 6 | 7 | //List 8 | $scope.list = function(){ 9 | basel.database.runAsync("SELECT * FROM "+$scope.table_name, function(data){ 10 | $scope.items = data; 11 | }); 12 | } 13 | 14 | //Saving 15 | $scope.save = function(){ 16 | if($scope.form[$scope.primary_key]){ 17 | //Edit 18 | var id = $scope.form[$scope.primary_key]; 19 | delete $scope.form[$scope.primary_key]; 20 | delete $scope.form.$$hashKey; //Apaga elemento $$hashKey do objeto 21 | basel.database.update($scope.table_name, $scope.form, {PRIMARY_KEY: id}); //entidade, dados, where 22 | }else{ 23 | //new 24 | basel.database.insert($scope.table_name, $scope.form); // entidade, dados 25 | } 26 | $scope.form = {}; 27 | $scope.list(); 28 | $('#CONTROLLER_NAME').modal('hide'); 29 | } 30 | 31 | // Cancel form 32 | $scope.cancel = function(){ 33 | $scope.form = {}; 34 | } 35 | 36 | //Abrindo para editar 37 | $scope.edit = function(data){ 38 | $scope.form = data; 39 | $('#CONTROLLER_NAME').modal('show'); 40 | } 41 | 42 | //Excluindo 43 | $scope.delete = function(data){ 44 | if(confirm("Are you sure?")){ 45 | basel.database.delete($scope.table_name, {PRIMARY_KEY: data[$scope.primary_key]}); 46 | $scope.list(); 47 | } 48 | } 49 | }); -------------------------------------------------------------------------------- /templates/crud.html: -------------------------------------------------------------------------------- 1 | <div ng-controller="CONTROLLER_NAME"> 2 | <div class="row"> 3 | <div class="col-md-8"> 4 | <button class="btn btn-primary" data-toggle="modal" data-target="#CONTROLLER_NAME"><span class="glyphicon glyphicon-plus"></span> New</button> 5 | </div> 6 | <div class="col-md-4"> 7 | <input class="form-control" placeholder="Search" ng-model="search"> 8 | </div> 9 | </div> 10 | <hr> 11 | <div class="row"> 12 | <div class="col-md-12"> 13 | <table class="table table-striped" ng-init="list()"> 14 | <thead class="basel-table-head"> 15 | 16 | </thead> 17 | <tbody class="basel-table-body"> 18 | 19 | </tbody> 20 | </table> 21 | </div> 22 | </div> 23 | <div class="row"> 24 | <div class="col-md-12 text-center"> 25 | <dir-pagination-controls> 26 | </dir-pagination-controls> 27 | </div> 28 | </div> 29 | 30 | <div class="modal fade" id="CONTROLLER_NAME" tabindex="-1" role="dialog" > 31 | <div class="modal-dialog" role="document"> 32 | <div class="modal-content"> 33 | <div class="modal-header"> 34 | <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> 35 | <h4 class="modal-title" id="myModalLabel"></h4> 36 | </div> 37 | <div class="modal-body"> 38 | <form class="basel-form"> 39 | 40 | </form> 41 | </div> 42 | <div class="modal-footer"> 43 | <button type="button" class="btn btn-default basel-btn-cancel" ng-click="cancel()" data-dismiss="modal">Cancel</button> 44 | <button type="button" class="btn btn-primary basel-btn-save" ng-click="save()">Save</button> 45 | </div> 46 | </div> 47 | </div> 48 | </div> 49 | </div> 50 | --------------------------------------------------------------------------------