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.
- 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:
|