├── app
└── templates
│ ├── empty
│ ├── src
│ │ ├── module.js
│ │ └── templates
│ │ │ └── template.html
│ ├── schema.json
│ └── form.json
│ ├── base
│ ├── README.md
│ ├── sources.json
│ ├── _gitignore
│ ├── demo
│ │ ├── main.css
│ │ └── index.html
│ ├── package.json
│ ├── bower.json
│ └── gulpfile.js
│ └── input
│ ├── form.json
│ ├── schema.json
│ └── src
│ ├── directives
│ └── update-on-blur.js
│ ├── module.js
│ └── templates
│ └── template.html
├── .jshintrc
├── .npmignore
├── .gitignore
├── .jscsrc
├── README.md
├── package.json
├── LICENSE
└── index.js
/app/templates/empty/src/module.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/templates/empty/schema.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "esnext": true
3 | }
4 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | index.js
2 | node_modules
3 |
--------------------------------------------------------------------------------
/app/templates/empty/form.json:
--------------------------------------------------------------------------------
1 | ["*"]
2 |
--------------------------------------------------------------------------------
/app/templates/base/README.md:
--------------------------------------------------------------------------------
1 | <%= name %>
2 |
--------------------------------------------------------------------------------
/app/templates/empty/src/templates/template.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/templates/base/sources.json:
--------------------------------------------------------------------------------
1 | <%- sources -%>
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | app/index.js
3 | app/index.js.map
4 |
--------------------------------------------------------------------------------
/.jscsrc:
--------------------------------------------------------------------------------
1 | {
2 | "preset": "airbnb",
3 | "esnext": true
4 | }
5 |
--------------------------------------------------------------------------------
/app/templates/base/_gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | bower_components
3 |
--------------------------------------------------------------------------------
/app/templates/input/form.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "type": "",
4 | "key": "name",
5 | "myOwnFormOption": "Hello world!"
6 | }
7 | ]
8 |
--------------------------------------------------------------------------------
/app/templates/base/demo/main.css:
--------------------------------------------------------------------------------
1 | .debug .wrapper {
2 | border: 1px solid #d6d6d6;
3 | border-radius: 5px;
4 | margin: 10px 0;
5 | }
6 |
7 | .debug .wrapper > div > div {
8 | padding: 0 25px;
9 | }
10 |
--------------------------------------------------------------------------------
/app/templates/base/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "<%= paramName %>",
3 | "version": "1.0.0",
4 | "description": "<%= name %> add-on for Angular Schema Form.",
5 | "author": "<%= username %>",
6 | "license": "MIT",
7 | "devDependencies": {}
8 | }
9 |
--------------------------------------------------------------------------------
/app/templates/input/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "object",
3 | "properties": {
4 | "name": {
5 | "type": "string",
6 | "title": "Name",
7 | "description": "Name or alias",
8 | "maxLength": 10,
9 | "minLength": 2,
10 | "required": true
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/templates/base/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "<%= paramName %>",
3 | "version": "1.0.0",
4 | "license": "MIT",
5 | "author": "<%= username %>",
6 | "main": [
7 | "dist/<%= paramName %>.min.js"
8 | ],
9 | "keywords": [
10 | "angular-schema-form",
11 | "schema-form",
12 | "form",
13 | "json",
14 | "json-schema",
15 | "schema"
16 | ],
17 | "ignore": [
18 | "**/.*",
19 | "node_modules",
20 | "bower_components",
21 | "test",
22 | "tests"
23 | ],
24 | "devDependencies": {}
25 | }
26 |
--------------------------------------------------------------------------------
/app/templates/input/src/directives/update-on-blur.js:
--------------------------------------------------------------------------------
1 | angular.module('<%= module %>').directive('updateOnBlur', function () {
2 | return {
3 | restrict: 'E',
4 | require: 'ngModel',
5 | scope: {},
6 | template: '',
7 | link: function (scope, element, attrs, ngModel) {
8 | scope.modelValue = ngModel.$viewValue;
9 |
10 | scope.updateModel = function (modelValue) {
11 | ngModel.$setViewValue(modelValue);
12 | };
13 | },
14 | };
15 | });
16 |
--------------------------------------------------------------------------------
/app/templates/input/src/module.js:
--------------------------------------------------------------------------------
1 | angular.module('<%= module %>', [
2 | 'schemaForm',
3 | 'templates'
4 | ]).config(function(schemaFormDecoratorsProvider, sfBuilderProvider) {
5 |
6 | schemaFormDecoratorsProvider.defineAddOn(
7 | 'bootstrapDecorator', // Name of the decorator you want to add to.
8 | '<%= formType %>', // Form type that should render this add-on
9 | 'src/templates/<%= paramName %>.html', // Template name in $templateCache
10 | sfBuilderProvider.stdBuilders // List of builder functions to apply.
11 | );
12 |
13 | });
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Angular Schema Form Add-on Generator
2 | ====================================
3 |
4 | A Yeoman generator to scaffold a [Angular Schema Form](http://schemaform.io/) Add-on.
5 |
6 | Install
7 | ---------------
8 | `npm install -g yo gulp bower generator-angular-schema-form-add-on`
9 |
10 | Usage
11 | ---------------
12 | First create a directory
13 |
14 | `mkdir your-add-on && cd your-add-on`
15 |
16 | Run `yo` and select **Angular Schema Form Add On**
17 |
18 | OR
19 |
20 | Run `yo angular-schema-form-add-on`
21 |
22 | When yeoman is done, gulp default will minify and start a livereload server for you to test the add-on.
23 |
24 | Under development
25 | -----------------
26 | Right now we have support for one starting form type **input**.. You can also choose **empty** which doesnt give you any example, just all the dependencies you need
27 |
--------------------------------------------------------------------------------
/app/templates/input/src/templates/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{form.myOwnFormOption}}
5 |
6 |
7 |
8 | <% if (directive) { %>
9 |
10 | Blur this field to update the model.
11 | <% } else { %>
12 |
13 | <% } %>
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "generator-angular-schema-form-add-on",
3 | "version": "0.1.3",
4 | "description": "A Yeoman generator for Angular Schema Form Add-Ons.",
5 | "main": "app/index.js",
6 | "files": [
7 | "app"
8 | ],
9 | "keywords": [
10 | "yeoman-generator"
11 | ],
12 | "scripts": {
13 | "compile": "babel index.js --out-file app/index.js --source-maps",
14 | "watch": "babel index.js --watch --out-file app/index.js --source-maps",
15 | "prepublish": "npm run compile"
16 | },
17 | "babel": {
18 | "presets": [
19 | "es2015"
20 | ]
21 | },
22 | "repository": "json-schema-form/generator-angular-schema-form-add-on",
23 | "dependencies": {
24 | "babel-polyfill": "^6.5.0",
25 | "babel-preset-es2015": "^6.5.0",
26 | "camelcase": "^1.2.1",
27 | "chalk": "^1.1.1",
28 | "fs-promise": "^0.3.1",
29 | "fs-readdir-recursive": "^0.1.2",
30 | "q": "^1.4.1",
31 | "yeoman-generator": "^0.20.3",
32 | "yosay": "^1.1.0"
33 | },
34 | "license": "MIT",
35 | "devDependencies": {
36 | "babel-cli": "^6.5.1"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Simon Korn
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 |
--------------------------------------------------------------------------------
/app/templates/base/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var connect = require('gulp-connect');
3 | var uglify = require('gulp-uglify');
4 | var concat = require('gulp-concat');
5 | var rename = require('gulp-rename');
6 | var templateCache = require('gulp-angular-templatecache');
7 | var streamqueue = require('streamqueue');
8 | var fs = require('fs');
9 |
10 | gulp.task('default', ['minify', 'connect', 'watch']);
11 |
12 | gulp.task('connect', function () {
13 | connect.server({
14 | root: ['demo', './'],
15 | livereload: true,
16 | });
17 | });
18 |
19 | gulp.task('reload', ['minify'], function () {
20 | gulp.src('./dist/**/*.*').pipe(connect.reload());
21 | });
22 |
23 | gulp.task('watch', function () {
24 | gulp.watch(['./src/**', './demo/**'], ['reload']);
25 | });
26 |
27 | gulp.task('minify', function () {
28 | var files = JSON.parse(fs.readFileSync('sources.json', 'utf-8'));
29 | var stream = streamqueue({ objectMode: true },
30 | gulp.src(['src/templates/**/*.html']).pipe(templateCache({
31 | standalone: true,
32 | root: 'src/templates/',
33 | })),
34 | gulp.src(files)
35 | )
36 | .pipe(concat('<%= paramName %>.js'))
37 | .pipe(gulp.dest('./dist'))
38 | .pipe(uglify())
39 | .pipe(rename('<%= paramName %>.min.js'))
40 | .pipe(gulp.dest('./dist'));
41 |
42 | return stream;
43 | });
44 |
--------------------------------------------------------------------------------
/app/templates/base/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
29 | Testing <%= name %> ASF addon
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
Model
44 |
{{model | json}}
45 |
46 |
47 |
48 |
49 |
Form
50 |
{{debug.form | json}}
51 |
52 |
53 |
54 |
55 |
Schema
56 |
{{debug.schema | json}}
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import 'babel-polyfill';
2 | import { Base } from 'yeoman-generator';
3 | import yosay from 'yosay';
4 | import camelcase from 'camelcase';
5 | import chalk from 'chalk';
6 | import read from 'fs-readdir-recursive';
7 |
8 | class asfAddOnGenerator extends Base {
9 |
10 | constructor(...args) {
11 | super(...args);
12 |
13 | /* Setting up our config object
14 | */
15 | this.addon = {};
16 | }
17 |
18 | prompting() {
19 | /* Welcome the user!!
20 | */
21 | this.log(yosay(`Hello and welcome to the Angular Schema Form Add-on Generator!`));
22 |
23 | /* We tell yeoman we don't want to continue until we run our done().
24 | */
25 | const done = this.async();
26 |
27 | this.prompt([
28 | {
29 | type: 'input',
30 | name: 'name',
31 | message: 'Your add-on name',
32 | default: this.appname,
33 | },
34 | {
35 | type: 'list',
36 | name: 'type',
37 | message: 'What kind of form type do you want?',
38 | choices: ['input', 'empty'], /*, 'Radio', 'Checkbox', 'Array'*/
39 | default: 'input',
40 | },
41 | {
42 | type: 'confirm',
43 | name: 'useDirective',
44 | message: 'Do you want a directive added to your addon?',
45 | default: true,
46 | },
47 | {
48 | type: 'input',
49 | name: 'username',
50 | message: 'What\'s your Github username?',
51 | store: true,
52 | },
53 | ], (answers) => {
54 |
55 | /* Nice, we now have all the answers.
56 | */
57 | Object.assign(this.addon, answers);
58 |
59 | /* Changing cases
60 | */
61 | this.addon.module = camelcase(this.addon.name); // ex. add on > addOn
62 | this.addon.formType = this.addon.name.replace(/ /g, ''); // ex. add on > addon
63 | this.addon.paramName = this.addon.name.replace(/ /g, '-'); // ex. add on > add-on
64 |
65 | /* We are done here... Let's continue
66 | */
67 | done();
68 | });
69 | }
70 |
71 | configure() {
72 |
73 | /* Let's get a list of our base files and type specific files.
74 | */
75 | this.addon.files = {};
76 |
77 | /* I do not like this, it looks ugly too me. but hell, it works for now.
78 | */
79 | this.addon.files.base = read(`${this.templatePath()}/base`);
80 | this.addon.files[this.addon.type] = read(`${this.templatePath()}/${this.addon.type}/src`);
81 |
82 | if (!this.addon.useDirective) {
83 | this.addon.files[this.addon.type] = this.addon.files[this.addon.type].filter(dir => !dir.includes('directives'))
84 | }
85 |
86 | }
87 |
88 | writing() {
89 | const done = this.async();
90 | const schema = this.fs.read(this.templatePath(`${this.addon.type}/schema.json`));
91 | let form = this.fs.read(this.templatePath(`${this.addon.type}/form.json`));
92 |
93 | /* TODO: Just a fast and easy fix for now..
94 | */
95 | form = JSON.parse(form);
96 | if (form[0].hasOwnProperty('type')) {
97 | form[0].type = this.addon.formType;
98 | }
99 |
100 | const sources = [];
101 | const testModule = ['schemaForm'];
102 |
103 | if (this.addon.type !== 'empty') {
104 | testModule.push(this.addon.module);
105 | sources.push('src/module.js', 'src/**/*.js');
106 | }
107 |
108 | this.addon.files.base.forEach((file) => {
109 | /* What to inject in the test controller
110 | */
111 | const dest = file.replace('_', '.');
112 |
113 | /* Base files */
114 | this.fs.copyTpl(
115 | this.templatePath(this.templatePath('base/') + file),
116 | this.destinationPath('./') + dest,
117 | {
118 | name: this.addon.name,
119 | module: this.addon.module,
120 | testModuleInj: JSON.stringify(testModule),
121 | formType: this.addon.formType,
122 | paramName: this.addon.paramName,
123 | schema: schema,
124 | form: JSON.stringify(form),
125 | username: this.addon.username,
126 | sources: JSON.stringify(sources),
127 | }
128 | );
129 | });
130 |
131 | /* Type files */
132 | this.addon.files[this.addon.type].forEach((file) => {
133 | const dest = file.replace('_', '.')
134 | .replace('template.html', `${this.addon.paramName}.html`)
135 | .replace('template.js', `${this.addon.paramName}.js`);
136 |
137 | this.fs.copyTpl(
138 | this.templatePath(this.templatePath(`${this.addon.type}/src/`) + file),
139 | this.destinationPath('./src/') + dest,
140 | {
141 | name: this.addon.name,
142 | module: this.addon.module,
143 | formType: this.addon.formType,
144 | paramName: this.addon.paramName,
145 | directive: this.addon.useDirective,
146 | }
147 | );
148 | });
149 |
150 | done();
151 | }
152 |
153 | install() {
154 | const npmDevDeps = [
155 | 'gulp',
156 | 'gulp-angular-templatecache',
157 | 'gulp-concat',
158 | 'gulp-connect',
159 | 'gulp-livereload',
160 | 'gulp-rename',
161 | 'gulp-server-livereload',
162 | 'gulp-uglify',
163 | 'streamqueue',
164 | ];
165 |
166 | const bowerDevDeps = [
167 | 'angular-schema-form',
168 | 'angular-schema-form-bootstrap',
169 | 'bootstrap',
170 | ];
171 |
172 | this.log(chalk.white(`\nAlmost done! Just running ${chalk.green.bold('npm install')} and ${chalk.green.bold('bower install')} for you!\n`));
173 |
174 | this.npmInstall(npmDevDeps, { saveDev: true });
175 | this.bowerInstall(bowerDevDeps, { saveDev: true });
176 | }
177 |
178 | end() {
179 | this.log(chalk.green(`\nEverything is done! \nJust run ${chalk.bold.green('gulp')} to start a livereload server to test your addon.`));
180 | }
181 |
182 | }
183 |
184 | module.exports = asfAddOnGenerator;
185 |
--------------------------------------------------------------------------------