revelry_generate 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +50 -0
  3. data/lib/generate.rb +12 -0
  4. data/lib/rails/generators/generate/skeleton_generator.rb +55 -0
  5. data/lib/rails/generators/jbuilder_props/jbuilder_props_generator.rb +23 -0
  6. data/lib/rails/generators/jbuilder_props/templates/edit.json.jbuilder +2 -0
  7. data/lib/rails/generators/jbuilder_props/templates/index.json.jbuilder +2 -0
  8. data/lib/rails/generators/jbuilder_props/templates/new.json.jbuilder +2 -0
  9. data/lib/rails/generators/jbuilder_props/templates/show.json.jbuilder +4 -0
  10. data/lib/rails/generators/react_scaffold/react_scaffold_generator.rb +73 -0
  11. data/lib/rails/generators/react_scaffold/templates/edit.js.erb +31 -0
  12. data/lib/rails/generators/react_scaffold/templates/form.js.erb +50 -0
  13. data/lib/rails/generators/react_scaffold/templates/index.js.erb +36 -0
  14. data/lib/rails/generators/react_scaffold/templates/new.js.erb +29 -0
  15. data/lib/rails/generators/react_scaffold/templates/show.js.erb +26 -0
  16. data/skeletons/node-base/__generators__/post_scaffold.js +3 -0
  17. data/skeletons/node-base/__generators__/post_skeleton.rb +53 -0
  18. data/skeletons/node-base/package.json +41 -0
  19. data/skeletons/node-base/scripts/dev-server.sh +6 -0
  20. data/skeletons/node-base/scripts/js-builder.js +33 -0
  21. data/skeletons/node-base/scripts/manifest.js +44 -0
  22. data/skeletons/node-base/scripts/sass-builder.js +70 -0
  23. data/skeletons/node-base/src/app.js +72 -0
  24. data/skeletons/node-base/src/client.js +5 -0
  25. data/skeletons/node-base/src/client.scss +2 -0
  26. data/skeletons/node-base/src/components/authenticity.js +14 -0
  27. data/skeletons/node-base/src/components/base.js +25 -0
  28. data/skeletons/node-base/src/server.js +53 -0
  29. data/skeletons/node-base/src/views.js +2 -0
  30. metadata +73 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d9d2e764c813ca0e3076628ec050402bcd7dbace
4
+ data.tar.gz: 218c5def1b9c76d085da3936519ebb26d4121f88
5
+ SHA512:
6
+ metadata.gz: 2108a7ba12577c158c183e04b3ed86bcd9c52d4eb3c4b767e545e1b9b6670be2b33cbf0cd3d7eba6bee50c0020874363f39b6fd27dd2d948523880b40221b298
7
+ data.tar.gz: 58bb46d75c9ccbc4608b3782ceac73442c9e3f0faa05719c4037c637bc73fea353ca5474471c3575bbe88bcdf2e4e12b77883d4912ac87edc43ed044dfaddeb8
data/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # generate
2
+
3
+ Packages containing the application templates, scaffolds, and generators for the
4
+ Revelry 2016 Name TBD stack.
5
+
6
+ ## Using
7
+
8
+ ```
9
+ rails new app_name -m template.rb
10
+ ```
11
+
12
+ or
13
+
14
+ ```
15
+ bin/rake rails:template LOCATION=template.rb
16
+ ```
17
+
18
+ This will generate an app using the default skeleton. The skeleton will give you
19
+ further instructions from there.
20
+
21
+ ## node-base (default) skeleton
22
+
23
+ This provides a minimal skeleton for rails with rails-render-service and the
24
+ revelry framework. After creating a new app with the template (see above), you
25
+ can:
26
+
27
+ ### Start the rails server
28
+
29
+ ```
30
+ rails s
31
+ ```
32
+
33
+ ### Start the development render server
34
+
35
+ ```
36
+ npm run devserver
37
+ ```
38
+
39
+ (this will run the render server in node, and rebuild client & server-side JS
40
+ and scss)
41
+
42
+ ### Scaffold a new resource
43
+
44
+ Just do:
45
+
46
+ ```
47
+ rails g scaffold Article
48
+ ```
49
+
50
+ like a normal rails app.
data/lib/generate.rb ADDED
@@ -0,0 +1,12 @@
1
+ require 'rails'
2
+ require_relative './rails/generators/react_scaffold/react_scaffold_generator'
3
+ require_relative './rails/generators/jbuilder_props/jbuilder_props_generator'
4
+
5
+ module RevelryGenerate
6
+ class Engine < ::Rails::Engine
7
+ end
8
+
9
+ class Railtie < ::Rails::Railtie
10
+ config.app_generators.template_engine :react_scaffold
11
+ end
12
+ end
@@ -0,0 +1,55 @@
1
+ require 'rails/generators/base'
2
+
3
+ module RevelryGenerate
4
+ module Generators
5
+ class SkeletonGenerator < ::Rails::Generators::Base
6
+ # copy the original scaffold controller from rails
7
+ # otherwise it gets trumped by the one from jbuilder, which we don't want
8
+ def copy_scaffold_controller_from_rails
9
+ create_file scaffold_controller_destination_path, File.binread(scaffold_controller_source_path)
10
+ end
11
+
12
+ def run_skeleton_scripts
13
+ Dir.chdir gem_root do
14
+ system 'npm install'
15
+ unless $?.success?
16
+ puts "`npm install` failed. You may need to `cd #{gem_root} && npm install` manually."
17
+ end
18
+ end
19
+
20
+ inside do
21
+ system File.join(gem_root, 'scripts', 'skeleton.js')
22
+ end
23
+
24
+ try_after_hook
25
+ end
26
+
27
+ protected
28
+
29
+ def railties_root
30
+ Gem::Specification.find_by_name('railties').gem_dir
31
+ end
32
+
33
+ def scaffold_controller_source_path
34
+ File.join('lib/rails/generators/rails/scaffold_controller/templates/controller.rb'.split('/').unshift(railties_root))
35
+ end
36
+
37
+ def scaffold_controller_destination_path
38
+ File.join('lib/templates/rails/scaffold_controller/controller.rb'.split('/'))
39
+ end
40
+
41
+ def gem_root
42
+ spec = Gem::Specification.find_by_name("revelry_generate")
43
+ spec.gem_dir
44
+ end
45
+
46
+ def try_after_hook
47
+ hook_path = File.join(gem_root, 'skeletons', 'node-base', '__generators__', 'post_skeleton.rb')
48
+
49
+ return unless File.exist? hook_path
50
+ puts "rake rails:template LOCATION=#{hook_path}"
51
+ rake "rails:template LOCATION=#{hook_path}"
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,23 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/named_base'
3
+ require 'rails/generators/resource_helpers'
4
+ require 'generators/rails/jbuilder_generator'
5
+
6
+ module Rails
7
+ module Generators
8
+ class JbuilderPropsGenerator < Rails::Generators::JbuilderGenerator
9
+ source_root File.expand_path('../templates', __FILE__)
10
+
11
+ def copy_view_files
12
+ %w(index show new edit).each do |view|
13
+ filename = filename_with_extensions(view)
14
+ template filename, File.join('app/views', controller_file_path, filename)
15
+ end
16
+ end
17
+
18
+ def handler
19
+ :jbuilder_props
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,2 @@
1
+ json.name '<%= plural_table_name %>/edit'
2
+ json.<%= singular_table_name %> json_form(@<%= singular_table_name %>)
@@ -0,0 +1,2 @@
1
+ json.name '<%= plural_table_name %>/index'
2
+ json.<%= plural_table_name %> @<%= plural_table_name %>, <%= attributes_list_with_timestamps %>
@@ -0,0 +1,2 @@
1
+ json.name '<%= plural_table_name %>/new'
2
+ json.<%= singular_table_name %> json_form(@<%= singular_table_name %>)
@@ -0,0 +1,4 @@
1
+ json.name '<%= plural_table_name %>/show'
2
+ json.<%= singular_table_name %> do
3
+ json.extract! @<%= singular_table_name %>, <%= attributes_list_with_timestamps %>
4
+ end
@@ -0,0 +1,73 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/erb/scaffold/scaffold_generator'
3
+
4
+ module Rails
5
+ module Generators
6
+ class ReactScaffoldGenerator < Erb::Generators::ScaffoldGenerator
7
+ source_root File.expand_path("../templates", __FILE__)
8
+
9
+ def copy_view_files
10
+ available_views.each do |view|
11
+ filename = filename_with_extensions(view)
12
+ template "#{view}.js.erb", File.join(view_path, controller_file_path.camelize, filename)
13
+ try_after_hook(controller_file_path, view);
14
+ end
15
+ end
16
+
17
+ hook_for :form_builder, :as => :scaffold
18
+ hook_for :jbuilder_props, default: true
19
+
20
+ def copy_form_file
21
+ if options[:form_builder].nil?
22
+ filename = filename_with_extensions("form")
23
+ template "form.js.erb", File.join(view_path, controller_file_path.camelize, filename)
24
+ end
25
+ end
26
+
27
+ protected
28
+
29
+ def view_path
30
+ ENV['GENERATE_VIEW_PATH'] || 'src/components'
31
+ end
32
+
33
+ def view_index_path
34
+ ENV['GENERATE_INDEX_VIEW_PATH'] || 'src/views.js'
35
+ end
36
+
37
+ def view_file_path(resource, action)
38
+ path = Pathname.new(File.join(view_path, "#{resource}/#{action}"))
39
+ path.relative_path_from(Pathname.new(File.dirname(view_index_path)))
40
+ end
41
+
42
+ def gem_root
43
+ spec = Gem::Specification.find_by_name("revelry_generate")
44
+ spec.gem_dir
45
+ end
46
+
47
+ def available_views
48
+ %w(index edit show new)
49
+ end
50
+
51
+ def filename_with_extensions(name, format = self.format)
52
+ [name, handler].compact.join(".")
53
+ end
54
+
55
+ def handler
56
+ :js
57
+ end
58
+
59
+ def try_after_hook(resource, action)
60
+ hook_path = File.join(gem_root, 'skeletons', 'node-base', '__generators__', 'post_scaffold.js')
61
+
62
+ inside gem_root do
63
+ system 'npm install'
64
+ end
65
+
66
+ return unless File.exist? hook_path
67
+ puts "node #{hook_path} #{view_index_path} #{view_file_path(resource, action)} #{resource}/#{action} #{resource.camelize}#{action.camelize}"
68
+ # UpdateViewFile('src/views.js', 'components/message8s/edit', 'message8s/edit', 'Message8sEdit');
69
+ system "node #{hook_path} #{view_index_path} #{view_file_path(resource, action)} #{resource}/#{action} #{resource.camelize}#{action.camelize}"
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,31 @@
1
+ import React, {Component} from 'react'
2
+ import {Row, Col} from 'revelry/lib/components/grid'
3
+ import {AuthenticityTokenProvider} from 'revelry/lib/components/forms'
4
+ import {Link} from '../base'
5
+ import Form from './form'
6
+
7
+ export default class <%= plural_table_name.camelize %>New extends Component {
8
+ render() {
9
+ const {<%= singular_table_name %>} = this.props
10
+ return (
11
+ <div>
12
+ <Row>
13
+ <Col>
14
+ <h1>
15
+ <Link href="/<%= plural_table_name %>">
16
+ <%= plural_table_name.titleize %>
17
+ </Link> / <Link href={`/<%= plural_table_name %>/${<%= singular_table_name %>.id}`}>
18
+ {<%= singular_table_name %>.id}
19
+ </Link> / Edit
20
+ </h1>
21
+ </Col>
22
+ </Row>
23
+ <Row>
24
+ <Col>
25
+ <Form {...<%= singular_table_name %>} />
26
+ </Col>
27
+ </Row>
28
+ </div>
29
+ )
30
+ }
31
+ }
@@ -0,0 +1,50 @@
1
+ import React, {Component, PropTypes} from 'react'
2
+ import {Row, Col} from 'revelry/lib/components/grid'
3
+ import {Input, Textarea} from 'revelry/lib/components/forms'
4
+ import {Button} from 'revelry/lib/components/buttons'
5
+ import {FormDataProvider, PropsFor} from 'react-rails-forms'
6
+ import {Form} from '../base'
7
+
8
+ export default class <%= plural_table_name.camelize %>Form extends Component {
9
+ render() {
10
+ const {id} = this.props
11
+ const formProps = {
12
+ method: id ? 'put' : 'post',
13
+ action: id ? `/<%= plural_table_name %>/${id}` : `/<%= plural_table_name %>`,
14
+ }
15
+
16
+ return (
17
+ <FormDataProvider name="<%= singular_table_name %>" value={this.props}>
18
+ <Form {...formProps}>
19
+ <% attributes.each do |attribute| %>
20
+ <Row>
21
+ <% if attribute.password_digest? %>
22
+ <Col>
23
+ <PropsFor name="password">
24
+ <Input type="password" label="Password" />
25
+ </Props>
26
+ </Col>
27
+ <Col>
28
+ <PropsFor name="password_confirmation">
29
+ <Input type="password" label="Confirm password" />
30
+ </PropsFor>
31
+ </Col>
32
+ <% else %>
33
+ <Col>
34
+ <PropsFor name="<%= attribute.column_name %>">
35
+ <Input type="text" label="<%= attribute.column_name %>" />
36
+ </PropsFor>
37
+ </Col>
38
+ <% end %>
39
+ </Row>
40
+ <% end %>
41
+ <Row>
42
+ <Col>
43
+ <Button>Submit</Button>
44
+ </Col>
45
+ </Row>
46
+ </Form>
47
+ </FormDataProvider>
48
+ )
49
+ }
50
+ }
@@ -0,0 +1,36 @@
1
+ import React, {Component, PropTypes} from 'react'
2
+ import {Row, Col} from 'revelry/lib/components/grid'
3
+ import {Link} from '../base'
4
+
5
+ const <%= plural_table_name.camelize %>Item = (props, context) => (
6
+ <li>
7
+ <Link href={`/<%= plural_table_name %>/${props.id}`}>
8
+ {`<%= singular_table_name %> ${props.id}`}
9
+ </Link>
10
+ </li>
11
+ )
12
+
13
+ export default class <%= plural_table_name.camelize %>Index extends Component {
14
+ render() {
15
+ const {<%= plural_table_name %>} = this.props
16
+ return (
17
+ <div>
18
+ <Row>
19
+ <Col>
20
+ <h1><%= plural_table_name.titleize %></h1>
21
+ </Col>
22
+ </Row>
23
+ <Row>
24
+ <Col large={3}>
25
+ <Link className="button" href="/<%= plural_table_name %>/new">
26
+ Create a new <%= singular_table_name %>
27
+ </Link>
28
+ </Col>
29
+ <Col large={9}>
30
+ <ul>{<%= plural_table_name %>.map(<%= singular_table_name %> => <<%= plural_table_name.camelize %>Item key={<%= singular_table_name %>.id} {...<%= singular_table_name %>} />)}</ul>
31
+ </Col>
32
+ </Row>
33
+ </div>
34
+ )
35
+ }
36
+ }
@@ -0,0 +1,29 @@
1
+ import React, {Component} from 'react'
2
+ import {Row, Col} from 'revelry/lib/components/grid'
3
+ import {AuthenticityTokenProvider} from 'revelry/lib/components/forms'
4
+ import {Link} from '../base'
5
+ import Form from './form'
6
+
7
+ export default class <%= plural_table_name.camelize %>New extends Component {
8
+ render() {
9
+ const {<%= singular_table_name %>} = this.props
10
+ return (
11
+ <div>
12
+ <Row>
13
+ <Col>
14
+ <h1>
15
+ <Link href="/<%= plural_table_name %>">
16
+ <%= plural_table_name.titleize %>
17
+ </Link> / New
18
+ </h1>
19
+ </Col>
20
+ </Row>
21
+ <Row>
22
+ <Col>
23
+ <Form {...<%= singular_table_name %>} />
24
+ </Col>
25
+ </Row>
26
+ </div>
27
+ )
28
+ }
29
+ }
@@ -0,0 +1,26 @@
1
+ import React, {Component} from 'react'
2
+ import {Row, Col} from 'revelry/lib/components/grid'
3
+ import {Button} from 'revelry/lib/components/buttons'
4
+ import {Link} from '../base'
5
+
6
+ export default class <%= plural_table_name.camelize %>Show extends Component {
7
+ render() {
8
+ const {<%= singular_table_name %>} = this.props
9
+ return (
10
+ <div>
11
+ <Row>
12
+ <Col>
13
+ <h1>
14
+ <Link href="/<%= plural_table_name %>">
15
+ <%= plural_table_name.titleize %>
16
+ </Link> / {<%= singular_table_name %>.id}
17
+ </h1>
18
+ </Col>
19
+ <Col>
20
+ <Link href={`/<%= plural_table_name %>/${<%= singular_table_name %>.id}/edit`}>Edit</Link>
21
+ </Col>
22
+ </Row>
23
+ </div>
24
+ )
25
+ }
26
+ }
@@ -0,0 +1,3 @@
1
+ var UpdateViewFile = require('../../../scripts/utilities/update_views.js');
2
+
3
+ UpdateViewFile(process.argv[2], process.argv[3], process.argv[4], process.argv[5]);
@@ -0,0 +1,53 @@
1
+ append_file 'config/initializers/assets.rb', 'Rails.application.config.assets.precompile += %w( client.css client.js )'
2
+ application "config.assets.paths << Rails.root.join('build')"
3
+
4
+ inject_into_file 'config/application.rb',
5
+ after: "config.active_record.raise_in_transactional_callbacks = true\n" do <<-RUBY
6
+ "config.assets.paths << Rails.root.join('build')"
7
+ RUBY
8
+ end
9
+
10
+ inject_into_file 'app/assets/javascripts/application.js',
11
+ after: "//= require_tree .\n" do
12
+ <<-RUBY
13
+ //= require client\n
14
+ RUBY
15
+ end
16
+
17
+ inject_into_file 'app/assets/stylesheets/application.css',
18
+ after: " *= require_self\n" do
19
+ <<-RUBY
20
+ *= require client\n
21
+ RUBY
22
+ end
23
+
24
+ create_file 'README.md'
25
+ append_to_file 'README.md', <<-MD
26
+ ## Starting render server
27
+
28
+ To start the render server, do:
29
+
30
+ ```
31
+ npm run devserver
32
+ ```
33
+ MD
34
+
35
+ create_file 'app/views/layouts/application.json.jbuilder', <<-JBUILDER
36
+ json.name content_for?(:virtual_path) ? content_for(:virtual_path) : local_assigns[:virtual_path]
37
+ json.data do |data|
38
+ location = request.path.sub(/\..*$/, '') || '/'
39
+ qs = request.query_string
40
+ location << "?\#{qs}" unless qs.empty?
41
+ data.location location
42
+
43
+ data.flashes flash
44
+
45
+ data.authenticity_token_name request_forgery_protection_token
46
+ data.authenticity_token_value form_authenticity_token
47
+
48
+ data.merge! JSON.parse(yield)
49
+ end
50
+ JBUILDER
51
+
52
+ system('npm install')
53
+ system('cat README.md')
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "railsrenderexample",
3
+ "version": "1.0.0",
4
+ "description": "== README",
5
+ "main": "build/server.js",
6
+ "directories": {
7
+ "test": "test"
8
+ },
9
+ "scripts": {
10
+ "devserver": "./scripts/dev-server.sh",
11
+ "dev": "concurrently --kill-others \"rails s\" \"npm run devserver\"",
12
+ "test": "echo \"Error: no test specified\" && exit 1"
13
+ },
14
+ "author": "",
15
+ "license": "UNLICENSED",
16
+ "devDependencies": {
17
+ "nodemon": "^1.9.1"
18
+ },
19
+ "dependencies": {
20
+ "babel-cli": "^6.7.5",
21
+ "babel-preset-es2015": "^6.6.0",
22
+ "babel-preset-react": "^6.5.0",
23
+ "babel-preset-stage-0": "^6.5.0",
24
+ "babelify": "^7.2.0",
25
+ "browserify": "^13.0.0",
26
+ "concurrently": "^2.0.0",
27
+ "foundation-sites": "^6.2.1",
28
+ "fs-extra": "^0.26.5",
29
+ "glob": "^7.0.3",
30
+ "minimist": "^1.2.0",
31
+ "node-sass": "^3.4.2",
32
+ "react": "^0.14.7",
33
+ "react-dom": "^0.14.7",
34
+ "react-rails-forms": "github:revelrylabs/react-rails-forms",
35
+ "react-redux": "^4.4.5",
36
+ "rejax": "github:revelrylabs/rejax",
37
+ "rev-hash": "^1.0.0",
38
+ "revelry-components": "github:revelrylabs/revelry_core_node",
39
+ "sassy-npm-importer": "^1.0.2"
40
+ }
41
+ }
@@ -0,0 +1,6 @@
1
+ #!/bin/sh
2
+
3
+ node_modules/.bin/concurrently -k \
4
+ "env $(cat .env | xargs) node_modules/.bin/nodemon --exec node_modules/.bin/babel-node src/server.js" \
5
+ "./scripts/js-builder.js src/client.js build/client.js --watch" \
6
+ "./scripts/sass-builder.js src/client.scss build/client.css --watch"
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+
3
+ var fs = require("fs");
4
+ var browserify = require("browserify");
5
+ var nodemon = require('nodemon');
6
+
7
+ var argv = require('minimist')(process.argv.slice(2));
8
+ var rootFile = argv._[0];
9
+ var outFile = argv._[1];
10
+
11
+ function makeBundle(rootFile, outFile) {
12
+ browserify(rootFile, {debug: true, extensions: ['.js', '.json', '.es6']})
13
+ .transform("babelify", {presets: ["es2015", "react", "stage-0"]})
14
+ .bundle()
15
+ .pipe(fs.createWriteStream(outFile));
16
+ }
17
+
18
+ if(argv.watch) {
19
+ nodemon({
20
+ script: `./scripts/js-builder.js`,
21
+ args: [rootFile, outFile],
22
+ watch: ['src/'],
23
+ ext: 'js'
24
+ });
25
+
26
+ nodemon.on('start', function () {
27
+ console.log('Watch has started');
28
+ }).on('restart', function (files) {
29
+ console.log('Recompiling due to: ', files);
30
+ });
31
+ } else {
32
+ makeBundle(rootFile, outFile);
33
+ }
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env node
2
+
3
+ var fs = require('fs-extra');
4
+ var path = require('path');
5
+ var revHash = require('rev-hash');
6
+
7
+ var argv = require('minimist')(process.argv.slice(2));
8
+
9
+ var outFiles = argv._;
10
+ var manifestFile = outFiles.pop();
11
+
12
+ function makeManifest(outFiles, manifestFile) {
13
+ var file, dir, base, ext, contents, hash, newFile;
14
+ var manifest = {};
15
+ var copies = {};
16
+ for(file of outFiles) {
17
+ dir = path.dirname(file);
18
+ ext = path.extname(file);
19
+ base = path.basename(file, ext);
20
+
21
+ contents = fs.readFileSync(file);
22
+ hash = revHash(contents);
23
+ newFile = `${base}-${hash}${ext}`;
24
+
25
+ copies[file] = path.join(dir, newFile);
26
+ manifest[`/assets/${base}${ext}`] = `/assets/${newFile}`;
27
+ }
28
+
29
+ copyFiles(copies);
30
+ writeManifest(manifest, manifestFile);
31
+ }
32
+
33
+ function copyFiles(copies) {
34
+ var ogFile;
35
+ for(ogFile in copies) {
36
+ fs.copy(ogFile, copies[ogFile]);
37
+ }
38
+ }
39
+
40
+ function writeManifest(manifest, manifestFile) {
41
+ fs.writeFileSync(path.resolve(manifestFile), JSON.stringify(manifest), {flag: 'w'});
42
+ }
43
+
44
+ makeManifest(outFiles, manifestFile);
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env node
2
+
3
+ var sass = require('node-sass');
4
+ var createImporter = require('sassy-npm-importer');
5
+ var path = require('path');
6
+ var fs = require('fs-extra');
7
+ var glob = require('glob');
8
+ var nodemon = require('nodemon');
9
+
10
+ var argv = require('minimist')(process.argv.slice(2));
11
+
12
+ if(argv._ < 2) {
13
+ console.log('sass-builder <inFile> <outFile>');
14
+ process.exit(1);
15
+ }
16
+
17
+ var rootFile = argv._[0];
18
+ var outFile = argv._[1];
19
+
20
+ function processFiles() {
21
+ var result = renderSync(rootFile, outFile);
22
+ writeCompiledFiles(result, outFile);
23
+ copyOriginals(rootFile, outFile);
24
+ }
25
+
26
+ function renderSync(rootFile, outFile) {
27
+ return sass.renderSync({
28
+ file: rootFile /*'/assets/src/' + path.basename(rootFile)*/,
29
+ outputStyle: 'compressed',
30
+ sourceMapRoot: '/assets/src',
31
+ outFile: outFile/*'/assets/' + path.basename(outFile)*/,
32
+ sourceMap: true,
33
+ importer: createImporter()
34
+ });
35
+ }
36
+
37
+ function writeCompiledFiles(result, outFile) {
38
+ var sourceMapFile = outFile + '.map'
39
+
40
+ fs.writeFileSync(outFile, result.css);
41
+ fs.writeFileSync(sourceMapFile, result.map);
42
+ }
43
+
44
+ function copyOriginals(rootFile, outFile) {
45
+ var srcDir = path.dirname(rootFile);
46
+ var buildDir = path.dirname(outFile);
47
+ glob(path.join(srcDir, '**/*.scss'), {}, function(err, files) {
48
+ var file = files
49
+ for(file of files) {
50
+ fs.copy(file, path.join(buildDir, file), function (err) {});
51
+ }
52
+ });
53
+ }
54
+
55
+ if(argv.watch) {
56
+ nodemon({
57
+ script: `./scripts/sass-builder.js`,
58
+ args: [rootFile, outFile],
59
+ watch: ['src/'],
60
+ ext: 'scss'
61
+ });
62
+
63
+ nodemon.on('start', function () {
64
+ console.log('Watch has started');
65
+ }).on('restart', function (files) {
66
+ console.log('Recompiling due to: ', files);
67
+ });
68
+ } else {
69
+ processFiles();
70
+ }
@@ -0,0 +1,72 @@
1
+ import React, {Component, PropTypes} from 'react'
2
+ import {createRejaxStore, Page, replacePage} from 'rejax'
3
+ import {Provider} from 'react-redux'
4
+ import views from './views'
5
+ import Authenticity from './components/authenticity'
6
+
7
+ export default class App extends Component {
8
+
9
+ static domId = '__APP__';
10
+ static views = views;
11
+
12
+ static hasView(key) {
13
+ return !!this.views[key]
14
+ }
15
+
16
+ static serverRender(ReactDOM, props) {
17
+ const appElement = <App {...props} />
18
+ const outputElement = (
19
+ <div
20
+ id={App.domId}
21
+ data-react-props={JSON.stringify(props)}
22
+ dangerouslySetInnerHTML={{__html: ReactDOM.renderToString(appElement)}}
23
+ />
24
+ )
25
+ return ReactDOM.renderToStaticMarkup(outputElement)
26
+ }
27
+
28
+ static clientRender(ReactDOM) {
29
+ function ready() {
30
+ const element = document.getElementById(App.domId)
31
+ const props = JSON.parse(element.getAttribute('data-react-props'))
32
+ ReactDOM.render(<App {...props} />, element)
33
+ }
34
+ if (document.readyState != 'loading'){
35
+ ready()
36
+ } else {
37
+ document.addEventListener('DOMContentLoaded', ready)
38
+ }
39
+ }
40
+
41
+ constructor(props) {
42
+ super(props)
43
+ this._store = createRejaxStore(props)
44
+ }
45
+
46
+ componentWillReceiveProps(props) {
47
+ this._store.dispatch(replacePage(props))
48
+ }
49
+
50
+ componentDidMount() {
51
+ history.replaceState(this._store.getState(), document.title, window.location)
52
+ window.addEventListener('popstate', (e) => {
53
+ if(e.state) {
54
+ this._store.dispatch(replacePage(e.state))
55
+ }
56
+ })
57
+ }
58
+
59
+ get pageProps() {
60
+ return this._store.getState().pageProps
61
+ }
62
+
63
+ render() {
64
+ return (
65
+ <Provider store={this._store}>
66
+ <Authenticity>
67
+ <Page views={views} name={this.pageProps.name} />
68
+ </Authenticity>
69
+ </Provider>
70
+ )
71
+ }
72
+ }
@@ -0,0 +1,5 @@
1
+ import App from './app'
2
+ import React from 'react'
3
+ import ReactDOM from 'react-dom'
4
+
5
+ App.clientRender(ReactDOM)
@@ -0,0 +1,2 @@
1
+ @import 'npm://foundation-sites/scss/foundation';
2
+ @include foundation-everything;
@@ -0,0 +1,14 @@
1
+ import {connect} from 'react-redux'
2
+ import {AuthenticityTokenProvider} from 'revelry/lib/components/forms'
3
+
4
+ const Authenticity = connect(
5
+ (state) => {
6
+ const {data} = state.pageProps
7
+ return {
8
+ name: data.authenticity_token_name,
9
+ value: data.authenticity_token_value,
10
+ }
11
+ },
12
+ )(AuthenticityTokenProvider)
13
+
14
+ export default Authenticity
@@ -0,0 +1,25 @@
1
+ import React, {Component} from 'react'
2
+ import {Form as RevelryForm} from 'revelry/lib/components/forms'
3
+ import {connectClickHandler, connectSubmitHandler} from 'rejax'
4
+
5
+ class DumbLink extends Component {
6
+ render() {
7
+ const {children, ...props} = this.props
8
+ return (
9
+ <a {...props}>{children}</a>
10
+ )
11
+ }
12
+ }
13
+ // export const Link = DumbLink
14
+ export const Link = connectClickHandler(DumbLink)
15
+
16
+ class DumbForm extends Component {
17
+ render() {
18
+ const {children, ...props} = this.props
19
+ return (
20
+ <RevelryForm {...props}>{children}</RevelryForm>
21
+ )
22
+ }
23
+ }
24
+ // export const Form = DumbForm
25
+ export const Form = connectSubmitHandler(DumbForm)
@@ -0,0 +1,53 @@
1
+ import http from 'http'
2
+ import express from 'express'
3
+ import path from 'path'
4
+ import bodyParser from 'body-parser'
5
+ import ReactDOMServer from 'react-dom/server'
6
+ import App from './app'
7
+
8
+ const app = express();
9
+ const port = path.resolve(process.env.RENDER_SERVICE_SOCKET)
10
+
11
+ app.use(bodyParser.json())
12
+
13
+ app.get('/*', function(req, res, next) {
14
+ const name = req.params[0]
15
+ try {
16
+ res.status(App.hasView(name) ? 200 : 404).end()
17
+ } catch(err) {
18
+ next(err)
19
+ }
20
+ })
21
+
22
+ app.post('/', function(req, res, next) {
23
+ try {
24
+ const output = App.serverRender(ReactDOMServer, req.body)
25
+ res.status(200).end(output)
26
+ } catch(err) {
27
+ next(err)
28
+ }
29
+ })
30
+
31
+ app.use(function(err, req, res, next) {
32
+ console.error(err.stack)
33
+ next(err)
34
+ })
35
+
36
+ app.use(function(err, req, res, next) {
37
+ res.status(500).end(err.stack)
38
+ })
39
+
40
+ const server = http.createServer(app)
41
+ server.listen(port)
42
+
43
+ function terminate() {
44
+ server.close(function() {
45
+ process.exit(0);
46
+ });
47
+ }
48
+
49
+ process.on('SIGTERM', terminate);
50
+ process.on('SIGINT', terminate);
51
+ process.once('SIGUSR2', terminate);
52
+
53
+ console.log(`Render service listening on ${port}`)
@@ -0,0 +1,2 @@
1
+ export default {
2
+ }
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: revelry_generate
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Robert Prehn
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-06-15 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: ''
14
+ email:
15
+ - robert@revelry.co
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - README.md
21
+ - lib/generate.rb
22
+ - lib/rails/generators/generate/skeleton_generator.rb
23
+ - lib/rails/generators/jbuilder_props/jbuilder_props_generator.rb
24
+ - lib/rails/generators/jbuilder_props/templates/edit.json.jbuilder
25
+ - lib/rails/generators/jbuilder_props/templates/index.json.jbuilder
26
+ - lib/rails/generators/jbuilder_props/templates/new.json.jbuilder
27
+ - lib/rails/generators/jbuilder_props/templates/show.json.jbuilder
28
+ - lib/rails/generators/react_scaffold/react_scaffold_generator.rb
29
+ - lib/rails/generators/react_scaffold/templates/edit.js.erb
30
+ - lib/rails/generators/react_scaffold/templates/form.js.erb
31
+ - lib/rails/generators/react_scaffold/templates/index.js.erb
32
+ - lib/rails/generators/react_scaffold/templates/new.js.erb
33
+ - lib/rails/generators/react_scaffold/templates/show.js.erb
34
+ - skeletons/node-base/__generators__/post_scaffold.js
35
+ - skeletons/node-base/__generators__/post_skeleton.rb
36
+ - skeletons/node-base/package.json
37
+ - skeletons/node-base/scripts/dev-server.sh
38
+ - skeletons/node-base/scripts/js-builder.js
39
+ - skeletons/node-base/scripts/manifest.js
40
+ - skeletons/node-base/scripts/sass-builder.js
41
+ - skeletons/node-base/src/app.js
42
+ - skeletons/node-base/src/client.js
43
+ - skeletons/node-base/src/client.scss
44
+ - skeletons/node-base/src/components/authenticity.js
45
+ - skeletons/node-base/src/components/base.js
46
+ - skeletons/node-base/src/server.js
47
+ - skeletons/node-base/src/views.js
48
+ homepage: https://github.com/revelrylabs/generate.git
49
+ licenses:
50
+ - MIT
51
+ metadata: {}
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 2.4.5.1
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: ''
72
+ test_files: []
73
+ has_rdoc: