diff --git a/.gitignore b/.gitignore index 3c3629e..0034f75 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ node_modules +app/index.js +app/index.js.map diff --git a/.jscsrc b/.jscsrc index 1797133..796ffa0 100644 --- a/.jscsrc +++ b/.jscsrc @@ -1,3 +1,4 @@ { - + "preset": "airbnb", + "esnext": true } diff --git a/.jshintrc b/.jshintrc index 1797133..a5aaaed 100644 --- a/.jshintrc +++ b/.jshintrc @@ -1,3 +1,3 @@ { - + "esnext": true } diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..f1faa39 --- /dev/null +++ b/.npmignore @@ -0,0 +1,2 @@ +index.js +node_modules diff --git a/LICENSE b/LICENSE index e55c56d..44d361c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015 Textalk +Copyright (c) 2015 Simon Korn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/app/index.js b/app/index.js deleted file mode 100644 index f9fa97e..0000000 --- a/app/index.js +++ /dev/null @@ -1,168 +0,0 @@ -var generators = require('yeoman-generator'); -var chalk = require('chalk'); -var path = require('path'); -var fsp = require('fs-promise'); -var q = require('q'); -var read = require('fs-readdir-recursive'); -var camelcase = require('camelcase'); - -module.exports = generators.Base.extend({ - - init: function() { - - /* Welcome the user!! - */ - this.log(chalk.blue.bold('.-========================-.')); - this.log(chalk.blue.bold('|| ||')); - this.log(chalk.blue.bold('|| ' + chalk.yellow('Angular schema form') + ' ||')); - this.log(chalk.blue.bold('|| ' + chalk.yellow('Add-on generator') + ' ||')); - this.log(chalk.blue.bold('|| ||')); - this.log(chalk.blue.bold('\'-========================-\'\n')); - - /* Setting up our config object - */ - this.addon = {files: {}}; - }, - - prompting: function() { - /* We tell yeoman we don't want to continue until we run our done(). - */ - var done = this.async(); - - this.prompt([{ - type: 'input', - name: 'name', - message: 'Your add-on name', - default: this.appname - }, - { - type: 'list', - name: 'type', - message: 'What kind of form type do you want?', - choices: ['Input' /*, 'Radio', 'Checkbox', 'Array'*/, 'Empty' ], - default: 'Input' - }], function(answers) { - - /* Nice, we now have the answers. let's put it in our config. - */ - this.addon.name = answers.name; - this.addon.type = answers.type; - - /* Changing cases - */ - this.addon.type = this.addon.type.toLowerCase(); // ex. Input > input - this.addon.directive = camelcase(this.addon.name); // ex. add on > addOn - this.addon.typeName = this.addon.name.replace(/ /g, ''); // ex. add on > addon - this.addon.paramName = this.addon.name.replace(/ /g, '-'); // ex. add on > add-on - - /* We are done here... Let's continue - */ - done(); - }.bind(this)); - - }, - - configure: function() { - - var done = this.async(); - - /* Let's get a list of our base files and type specific files. - */ - this.addon.files.base = read(this.templatePath() + '/base'); - this.addon.files[this.addon.type] = read(this.templatePath() + '/' + this.addon.type + '/src'); - - done(); - }, - - writing: function() { - - var done = this.async(); - - var schema = this.fs.read(this.templatePath(this.addon.type + '/schema.json')); - var form = this.fs.read(this.templatePath(this.addon.type + '/form.json')); - - /* Just a fast and easy fix.. because current version isn't working */ - form = JSON.parse(form); - if (form[0].hasOwnProperty('type')) { - form[0].type = this.addon.typeName; - } - - this.addon.files.base.forEach(function(file) { - // what to inject in the test controller - var testModule = ['schemaForm']; - var dest = file.replace('_', '.') - .replace('module.js', this.addon.paramName + '.js'); - - if (this.addon.type !== 'empty') { - testModule.push(this.addon.directive); - } - - /* Base files */ - this.fs.copyTpl( - this.templatePath(this.templatePath('base/') + file), - this.destinationPath('./') + dest, - { - name: this.addon.name, - directive: this.addon.directive, - testModuleInj: JSON.stringify(testModule), - typeName: this.addon.typeName, - paramName: this.addon.paramName, - schema: schema, - form: JSON.stringify(form) - } - ); - }.bind(this)); - - /* Type files */ - this.addon.files[this.addon.type].forEach(function(file) { - var dest = file.replace('_', '.') - .replace('template.html', this.addon.paramName + '.html') - .replace('module.js', this.addon.paramName + '.js'); - - this.fs.copyTpl( - this.templatePath(this.templatePath(this.addon.type + '/src/') + file), - this.destinationPath('./src/') + dest, - { - name: this.addon.name, - directive: this.addon.directive, - typeName: this.addon.typeName, - paramName: this.addon.paramName - } - ); - }.bind(this)); - - done(); - - }, - - install: function() { - var npmDevDeps = [ - "gulp", - "gulp-angular-templatecache", - "gulp-concat", - "gulp-connect", - "gulp-livereload", - "gulp-rename", - "gulp-server-livereload", - "gulp-uglify", - "streamqueue" - ]; - - var bowerDevDeps = [ - 'angular-schema-form', - 'angular-schema-form-bootstrap', - 'bootstrap' - ]; - - console.log(chalk.white('\nAlmost done! Just running ' + chalk.green.bold('npm install') + ' and ' + chalk.green.bold('bower install') + ' for you!\n')); - - this.npmInstall(npmDevDeps, { 'saveDev': true }); - this.bowerInstall(bowerDevDeps, { 'saveDev': true }); - - }, - - end: function() { - console.log(chalk.green('\nEverything is done! \nJust run ' + chalk.bold.green('gulp') + ' to start a livereload server to test your addon.')); - } - -}); diff --git a/app/templates/base/bower.json b/app/templates/base/bower.json index 947a693..a133dac 100644 --- a/app/templates/base/bower.json +++ b/app/templates/base/bower.json @@ -2,6 +2,18 @@ "name": "<%= paramName %>", "version": "1.0.0", "license": "MIT", + "author": "<%= username %>", + "main": [ + "dist/<%= paramName %>.min.js" + ], + "keywords": [ + "angular-schema-form", + "schema-form", + "form", + "json", + "json-schema", + "schema" + ], "ignore": [ "**/.*", "node_modules", diff --git a/app/templates/base/test/index.html b/app/templates/base/demo/index.html similarity index 95% rename from app/templates/base/test/index.html rename to app/templates/base/demo/index.html index 295bde3..4baf743 100644 --- a/app/templates/base/test/index.html +++ b/app/templates/base/demo/index.html @@ -21,7 +21,7 @@ $scope.model = {}; - $scope.debug = {schema: $scope.schema, form: $scope.form}; + $scope.debug = {schema: angular.copy($scope.schema), form: angular.copy($scope.form)}; }); diff --git a/app/templates/base/test/main.css b/app/templates/base/demo/main.css similarity index 100% rename from app/templates/base/test/main.css rename to app/templates/base/demo/main.css diff --git a/app/templates/base/gulp/index.js b/app/templates/base/gulp/index.js deleted file mode 100644 index 5c6165a..0000000 --- a/app/templates/base/gulp/index.js +++ /dev/null @@ -1,7 +0,0 @@ -var fs = require('fs'); -var tasks = fs.readdirSync('./gulp/tasks'); -var gulp = require('gulp'); - -tasks.forEach(function(task) { - require('./tasks/' + task); -}); diff --git a/app/templates/base/gulp/tasks/default.js b/app/templates/base/gulp/tasks/default.js deleted file mode 100644 index 02baec4..0000000 --- a/app/templates/base/gulp/tasks/default.js +++ /dev/null @@ -1,3 +0,0 @@ -var gulp = require('gulp'); - -gulp.task('default', ['minify', 'connect', 'watch']); diff --git a/app/templates/base/gulp/tasks/minify.js b/app/templates/base/gulp/tasks/minify.js deleted file mode 100644 index 738ddaf..0000000 --- a/app/templates/base/gulp/tasks/minify.js +++ /dev/null @@ -1,24 +0,0 @@ -var gulp = require('gulp'); -var uglify = require('gulp-uglify'); -var concat = require('gulp-concat'); -var rename = require('gulp-rename'); -var templateCache = require('gulp-angular-templatecache'); -var streamqueue = require('streamqueue'); - -gulp.task('minify', function() { - - var stream = streamqueue({objectMode: true}, - gulp.src(['src/templates/**/*.html']).pipe(templateCache({ - standalone: true, - root: 'src/templates/' - })), - gulp.src(['src/*.js']) - ) - .pipe(concat('<%= paramName %>.js')) - .pipe(gulp.dest('./dist')) - .pipe(uglify()) - .pipe(rename('<%= paramName %>.min.js')) - .pipe(gulp.dest('./dist')); - - return stream; -}); diff --git a/app/templates/base/gulp/tasks/server.js b/app/templates/base/gulp/tasks/server.js deleted file mode 100644 index 6b51986..0000000 --- a/app/templates/base/gulp/tasks/server.js +++ /dev/null @@ -1,17 +0,0 @@ -var gulp = require('gulp'); -var connect = require('gulp-connect'); - -gulp.task('connect', function() { - connect.server({ - root: ['test', './'], - livereload: true - }); -}); - -gulp.task('reload', ['minify'], function() { - gulp.src('./dist/**/*.*').pipe(connect.reload()); -}); - -gulp.task('watch', function() { - gulp.watch(['./src/**', './test/**'], ['reload']); -}); diff --git a/app/templates/base/gulpfile.js b/app/templates/base/gulpfile.js index 06249eb..95414ba 100644 --- a/app/templates/base/gulpfile.js +++ b/app/templates/base/gulpfile.js @@ -1 +1,43 @@ -require('./gulp'); +var gulp = require('gulp'); +var connect = require('gulp-connect'); +var uglify = require('gulp-uglify'); +var concat = require('gulp-concat'); +var rename = require('gulp-rename'); +var templateCache = require('gulp-angular-templatecache'); +var streamqueue = require('streamqueue'); +var fs = require('fs'); + +gulp.task('default', ['minify', 'connect', 'watch']); + +gulp.task('connect', function () { + connect.server({ + root: ['demo', './'], + livereload: true, + }); +}); + +gulp.task('reload', ['minify'], function () { + gulp.src('./dist/**/*.*').pipe(connect.reload()); +}); + +gulp.task('watch', function () { + gulp.watch(['./src/**', './demo/**'], ['reload']); +}); + +gulp.task('minify', function () { + var files = JSON.parse(fs.readFileSync('sources.json', 'utf-8')); + var stream = streamqueue({ objectMode: true }, + gulp.src(['src/templates/**/*.html']).pipe(templateCache({ + standalone: true, + root: 'src/templates/', + })), + gulp.src(files) + ) + .pipe(concat('<%= paramName %>.js')) + .pipe(gulp.dest('./dist')) + .pipe(uglify()) + .pipe(rename('<%= paramName %>.min.js')) + .pipe(gulp.dest('./dist')); + + return stream; +}); diff --git a/app/templates/base/package.json b/app/templates/base/package.json index d7f1dc6..7c2aa46 100644 --- a/app/templates/base/package.json +++ b/app/templates/base/package.json @@ -1,12 +1,8 @@ { "name": "<%= paramName %>", "version": "1.0.0", - "description": "", - "main": "gulpfile.js", - "directories": { - "test": "test" - }, - "author": "", + "description": "<%= name %> add-on for Angular Schema Form.", + "author": "<%= username %>", "license": "MIT", "devDependencies": {} } diff --git a/app/templates/base/sources.json b/app/templates/base/sources.json new file mode 100644 index 0000000..3f7325d --- /dev/null +++ b/app/templates/base/sources.json @@ -0,0 +1 @@ +<%- sources -%> diff --git a/app/templates/input/src/directives/update-on-blur.js b/app/templates/input/src/directives/update-on-blur.js new file mode 100644 index 0000000..0111530 --- /dev/null +++ b/app/templates/input/src/directives/update-on-blur.js @@ -0,0 +1,15 @@ +angular.module('<%= module %>').directive('updateOnBlur', function () { + return { + restrict: 'E', + require: 'ngModel', + scope: {}, + template: '', + link: function (scope, element, attrs, ngModel) { + scope.modelValue = ngModel.$viewValue; + + scope.updateModel = function (modelValue) { + ngModel.$setViewValue(modelValue); + }; + }, + }; +}); diff --git a/app/templates/input/src/module.js b/app/templates/input/src/module.js index e70e024..7cd33d5 100644 --- a/app/templates/input/src/module.js +++ b/app/templates/input/src/module.js @@ -1,11 +1,11 @@ -angular.module('<%= directive %>', [ +angular.module('<%= module %>', [ 'schemaForm', 'templates' ]).config(function(schemaFormDecoratorsProvider, sfBuilderProvider) { schemaFormDecoratorsProvider.defineAddOn( 'bootstrapDecorator', // Name of the decorator you want to add to. - '<%= typeName %>', // Form type that should render this add-on + '<%= formType %>', // Form type that should render this add-on 'src/templates/<%= paramName %>.html', // Template name in $templateCache sfBuilderProvider.stdBuilders // List of builder functions to apply. ); diff --git a/app/templates/input/src/templates/template.html b/app/templates/input/src/templates/template.html index 3903559..fcc82de 100644 --- a/app/templates/input/src/templates/template.html +++ b/app/templates/input/src/templates/template.html @@ -5,8 +5,12 @@

{{form.myOwnFormOption}}

- + <% if (directive) { %> + + Blur this field to update the model. + <% } else { %> + <% } %> diff --git a/index.js b/index.js new file mode 100644 index 0000000..083dff3 --- /dev/null +++ b/index.js @@ -0,0 +1,184 @@ +import 'babel-polyfill'; +import { Base } from 'yeoman-generator'; +import yosay from 'yosay'; +import camelcase from 'camelcase'; +import chalk from 'chalk'; +import read from 'fs-readdir-recursive'; + +class asfAddOnGenerator extends Base { + + constructor(...args) { + super(...args); + + /* Setting up our config object + */ + this.addon = {}; + } + + prompting() { + /* Welcome the user!! + */ + this.log(yosay(`Hello and welcome to the Angular Schema Form Add-on Generator!`)); + + /* We tell yeoman we don't want to continue until we run our done(). + */ + const done = this.async(); + + this.prompt([ + { + type: 'input', + name: 'name', + message: 'Your add-on name', + default: this.appname, + }, + { + type: 'list', + name: 'type', + message: 'What kind of form type do you want?', + choices: ['input', 'empty'], /*, 'Radio', 'Checkbox', 'Array'*/ + default: 'input', + }, + { + type: 'confirm', + name: 'useDirective', + message: 'Do you want a directive added to your addon?', + default: true, + }, + { + type: 'input', + name: 'username', + message: 'What\'s your Github username?', + store: true, + }, + ], (answers) => { + + /* Nice, we now have all the answers. + */ + Object.assign(this.addon, answers); + + /* Changing cases + */ + this.addon.module = camelcase(this.addon.name); // ex. add on > addOn + this.addon.formType = this.addon.name.replace(/ /g, ''); // ex. add on > addon + this.addon.paramName = this.addon.name.replace(/ /g, '-'); // ex. add on > add-on + + /* We are done here... Let's continue + */ + done(); + }); + } + + configure() { + + /* Let's get a list of our base files and type specific files. + */ + this.addon.files = {}; + + /* I do not like this, it looks ugly too me. but hell, it works for now. + */ + this.addon.files.base = read(`${this.templatePath()}/base`); + this.addon.files[this.addon.type] = read(`${this.templatePath()}/${this.addon.type}/src`); + + if (!this.addon.useDirective) { + this.addon.files[this.addon.type] = this.addon.files[this.addon.type].filter(dir => !dir.includes('directives')) + } + + } + + writing() { + const done = this.async(); + const schema = this.fs.read(this.templatePath(`${this.addon.type}/schema.json`)); + let form = this.fs.read(this.templatePath(`${this.addon.type}/form.json`)); + + /* TODO: Just a fast and easy fix for now.. + */ + form = JSON.parse(form); + if (form[0].hasOwnProperty('type')) { + form[0].type = this.addon.formType; + } + + const sources = []; + const testModule = ['schemaForm']; + + if (this.addon.type !== 'empty') { + testModule.push(this.addon.module); + sources.push('src/module.js', 'src/**/*.js'); + } + + this.addon.files.base.forEach((file) => { + /* What to inject in the test controller + */ + const dest = file.replace('_', '.'); + + /* Base files */ + this.fs.copyTpl( + this.templatePath(this.templatePath('base/') + file), + this.destinationPath('./') + dest, + { + name: this.addon.name, + module: this.addon.module, + testModuleInj: JSON.stringify(testModule), + formType: this.addon.formType, + paramName: this.addon.paramName, + schema: schema, + form: JSON.stringify(form), + username: this.addon.username, + sources: JSON.stringify(sources), + } + ); + }); + + /* Type files */ + this.addon.files[this.addon.type].forEach((file) => { + const dest = file.replace('_', '.') + .replace('template.html', `${this.addon.paramName}.html`) + .replace('template.js', `${this.addon.paramName}.js`); + + this.fs.copyTpl( + this.templatePath(this.templatePath(`${this.addon.type}/src/`) + file), + this.destinationPath('./src/') + dest, + { + name: this.addon.name, + module: this.addon.module, + formType: this.addon.formType, + paramName: this.addon.paramName, + directive: this.addon.useDirective, + } + ); + }); + + done(); + } + + install() { + const npmDevDeps = [ + 'gulp', + 'gulp-angular-templatecache', + 'gulp-concat', + 'gulp-connect', + 'gulp-livereload', + 'gulp-rename', + 'gulp-server-livereload', + 'gulp-uglify', + 'streamqueue', + ]; + + const bowerDevDeps = [ + 'angular-schema-form', + 'angular-schema-form-bootstrap', + 'bootstrap', + ]; + + this.log(chalk.white(`\nAlmost done! Just running ${chalk.green.bold('npm install')} and ${chalk.green.bold('bower install')} for you!\n`)); + + this.npmInstall(npmDevDeps, { saveDev: true }); + this.bowerInstall(bowerDevDeps, { saveDev: true }); + } + + end() { + this.log(chalk.green(`\nEverything is done! \nJust run ${chalk.bold.green('gulp')} to start a livereload server to test your addon.`)); + } + +} + +module.exports = asfAddOnGenerator; diff --git a/package.json b/package.json index cb2ebfc..72e8ea5 100644 --- a/package.json +++ b/package.json @@ -2,20 +2,37 @@ "name": "generator-angular-schema-form-add-on", "version": "0.1.3", "description": "A Yeoman generator for Angular Schema Form Add-Ons.", + "main": "app/index.js", "files": [ "app" ], "keywords": [ "yeoman-generator" ], - "repository": "textalk/generator-angular-schema-form-add-on", + "scripts": { + "compile": "babel index.js --out-file app/index.js --source-maps", + "watch": "babel index.js --watch --out-file app/index.js --source-maps", + "prepublish": "npm run compile" + }, + "babel": { + "presets": [ + "es2015" + ] + }, + "repository": "json-schema-form/generator-angular-schema-form-add-on", "dependencies": { + "babel-polyfill": "^6.5.0", + "babel-preset-es2015": "^6.5.0", "camelcase": "^1.2.1", "chalk": "^1.1.1", "fs-promise": "^0.3.1", "fs-readdir-recursive": "^0.1.2", "q": "^1.4.1", - "yeoman-generator": "^0.20.3" + "yeoman-generator": "^0.20.3", + "yosay": "^1.1.0" }, - "license": "MIT" + "license": "MIT", + "devDependencies": { + "babel-cli": "^6.5.1" + } }