revelry_generate 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +50 -0
- data/lib/generate.rb +12 -0
- data/lib/rails/generators/generate/skeleton_generator.rb +55 -0
- data/lib/rails/generators/jbuilder_props/jbuilder_props_generator.rb +23 -0
- data/lib/rails/generators/jbuilder_props/templates/edit.json.jbuilder +2 -0
- data/lib/rails/generators/jbuilder_props/templates/index.json.jbuilder +2 -0
- data/lib/rails/generators/jbuilder_props/templates/new.json.jbuilder +2 -0
- data/lib/rails/generators/jbuilder_props/templates/show.json.jbuilder +4 -0
- data/lib/rails/generators/react_scaffold/react_scaffold_generator.rb +73 -0
- data/lib/rails/generators/react_scaffold/templates/edit.js.erb +31 -0
- data/lib/rails/generators/react_scaffold/templates/form.js.erb +50 -0
- data/lib/rails/generators/react_scaffold/templates/index.js.erb +36 -0
- data/lib/rails/generators/react_scaffold/templates/new.js.erb +29 -0
- data/lib/rails/generators/react_scaffold/templates/show.js.erb +26 -0
- data/skeletons/node-base/__generators__/post_scaffold.js +3 -0
- data/skeletons/node-base/__generators__/post_skeleton.rb +53 -0
- data/skeletons/node-base/package.json +41 -0
- data/skeletons/node-base/scripts/dev-server.sh +6 -0
- data/skeletons/node-base/scripts/js-builder.js +33 -0
- data/skeletons/node-base/scripts/manifest.js +44 -0
- data/skeletons/node-base/scripts/sass-builder.js +70 -0
- data/skeletons/node-base/src/app.js +72 -0
- data/skeletons/node-base/src/client.js +5 -0
- data/skeletons/node-base/src/client.scss +2 -0
- data/skeletons/node-base/src/components/authenticity.js +14 -0
- data/skeletons/node-base/src/components/base.js +25 -0
- data/skeletons/node-base/src/server.js +53 -0
- data/skeletons/node-base/src/views.js +2 -0
- 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,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,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,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}`)
|
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:
|