revelry_generate 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: