js_from_routes 1.0.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 +152 -0
- data/lib/js_from_routes.rb +7 -0
- data/lib/js_from_routes/generator.rb +142 -0
- data/lib/js_from_routes/railtie.rb +25 -0
- data/lib/js_from_routes/version.rb +6 -0
- data/spec/js_from_routes/js_from_routes_spec.rb +75 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/support/sample_app/app/controllers/application_controller.rb +2 -0
- data/spec/support/sample_app/app/controllers/comments_controller.rb +2 -0
- data/spec/support/sample_app/app/controllers/user_preferences_controller.rb +2 -0
- data/spec/support/sample_app/app/controllers/video_clips_controller.rb +2 -0
- data/spec/support/sample_app/app/controllers/welcome_controller.rb +2 -0
- data/spec/support/sample_app/app/mailers/application_mailer.rb +4 -0
- data/spec/support/sample_app/config/application.rb +20 -0
- data/spec/support/sample_app/config/boot.rb +4 -0
- data/spec/support/sample_app/config/environment.rb +5 -0
- data/spec/support/sample_app/config/environments/development.rb +33 -0
- data/spec/support/sample_app/config/initializers/application_controller_renderer.rb +8 -0
- data/spec/support/sample_app/config/initializers/assets.rb +14 -0
- data/spec/support/sample_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/support/sample_app/config/initializers/content_security_policy.rb +30 -0
- data/spec/support/sample_app/config/initializers/cookies_serializer.rb +5 -0
- data/spec/support/sample_app/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/support/sample_app/config/initializers/inflections.rb +16 -0
- data/spec/support/sample_app/config/initializers/mime_types.rb +4 -0
- data/spec/support/sample_app/config/initializers/wrap_parameters.rb +14 -0
- data/spec/support/sample_app/config/puma.rb +38 -0
- data/spec/support/sample_app/config/routes.rb +22 -0
- data/spec/support/sample_app/node_modules/node-sass/src/libsass/extconf.rb +6 -0
- metadata +141 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b404b3e7cc0394a4a79ecb225b36fbcf0f29d07391ee6df877cd068f1af438fb
|
4
|
+
data.tar.gz: 646668b779ea86c0aeee8327fba4355619ac2d72231e9053e4ec1569a3fc4293
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8fd27cf2b1388f455c42a68b3ba892f9344e13cae2f46654e4ec0a9554c1d3e932366898ffdf1860027b0eec0a4be1112f7289d40f22a5426889ae4c16766d8c
|
7
|
+
data.tar.gz: ce4f56fd37aa81378d41633da4eb7b59486052115d4a9224e472d7f14330e62d39e14f5ef8d2ea8f7a2f8e03e9f6221419d6ee73a764145aac7a47b0030726b0
|
data/README.md
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
<h1 align="center">
|
2
|
+
JS From Rails Routes
|
3
|
+
<p align="center">
|
4
|
+
<a href="https://rubygems.org/gems/js_from_routes"><img alt="Gem Version" src="https://img.shields.io/gem/v/js_from_routes.svg?colorB=e9573f"/></a>
|
5
|
+
<a href="https://travis-ci.org/ElMassimo/js_from_routes"><img alt="Build Status" src="https://travis-ci.org/ElMassimo/js_from_routes.svg"/></a>
|
6
|
+
<a href="https://codeclimate.com/github/ElMassimo/js_from_routes"><img alt="Coverage Status" src="https://codeclimate.com/github/ElMassimo/request_store_rails/badges/coverage.svg"/></a>
|
7
|
+
<a href="https://codeclimate.com/github/ElMassimo/js_from_routes"><img alt="Code Quality" src="https://codeclimate.com/github/ElMassimo/js_from_routes/badges/gpa.svg"/></a>
|
8
|
+
<a href="http://inch-ci.org/github/ElMassimo/js_from_routes"><img alt="Inline docs" src="http://inch-ci.org/github/ElMassimo/js_from_routes.svg"/></a>
|
9
|
+
<a href="https://github.com/ElMassimo/js_from_routes/blob/master/LICENSE.txt"><img alt="License" src="https://img.shields.io/badge/license-MIT-428F7E.svg"/></a>
|
10
|
+
</p>
|
11
|
+
</h1>
|
12
|
+
|
13
|
+
_JS from Routes_ helps you by automatically generating path and API helpers from
|
14
|
+
Rails route definitions, allowing you to save development effort and focus on
|
15
|
+
the things that matter.
|
16
|
+
|
17
|
+
## Why? 🤔
|
18
|
+
|
19
|
+
Path helpers in Rails are useful to ensure the constructed URLs match endpoints
|
20
|
+
defined in the app.
|
21
|
+
|
22
|
+
With this library, it's possible the enjoy the same benefits in JS:
|
23
|
+
|
24
|
+
- No need to manually specify the URL, preventing mistakes and saving development time.
|
25
|
+
- If an action is renamed or removed, the helper ceases to exist, which causes
|
26
|
+
an error that is easier to detect than a 404.
|
27
|
+
- We can embed the the HTTP verb in the helper. Changing the verb in the route causes the JS
|
28
|
+
code to be regenerated, no need to update the consumer!
|
29
|
+
|
30
|
+
### Installation 💿
|
31
|
+
|
32
|
+
Add this line to your application's Gemfile:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
gem 'js_from_routes'
|
36
|
+
```
|
37
|
+
|
38
|
+
And then execute:
|
39
|
+
|
40
|
+
$ bundle
|
41
|
+
|
42
|
+
Or install it yourself as:
|
43
|
+
|
44
|
+
$ gem install js_from_routes
|
45
|
+
|
46
|
+
### Usage 🚀
|
47
|
+
|
48
|
+
#### 1. Specify the Rails routes you want to export
|
49
|
+
|
50
|
+
Use the `export` attribute to determine which [routes](https://github.com/ElMassimo/js_from_routes/blob/master/spec/support/sample_app/config/routes.rb#L6) should be taken into account when generating JS.
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
Rails.application.routes.draw do
|
54
|
+
resources :video_clips, export: true do
|
55
|
+
get :download, on: :member, export: :path_only
|
56
|
+
get :trending, on: :collection, export: false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
#### 2. Generate JS code from your routes
|
62
|
+
|
63
|
+
This is usually done automatically the next time you make a request to your
|
64
|
+
Rails server (such as when you refresh the page), which causes Rails reloader to
|
65
|
+
kick in, and the routes to be generated.
|
66
|
+
|
67
|
+
If you are not running a local development server, or prefer to do it manually,
|
68
|
+
you can use a rake task instead:
|
69
|
+
|
70
|
+
```
|
71
|
+
bin/rake js_from_routes:generate
|
72
|
+
```
|
73
|
+
|
74
|
+
#### 3. Use the generated code in your JS application
|
75
|
+
|
76
|
+
This can happen in many [different ways](https://github.com/ElMassimo/js_from_routes/blob/master/spec/support/sample_app/app/javascript/Videos.vue#L10), but to illustrate using the example above:
|
77
|
+
|
78
|
+
```js
|
79
|
+
import VideoClipsRequests from '@requests/VideoClipsRequests'
|
80
|
+
|
81
|
+
VideoClipsRequests.get({ id: 'oHg5SJYRHA0' }).then(displayVideo)
|
82
|
+
|
83
|
+
const path = VideoClipsRequests.downloadPath({ id })
|
84
|
+
```
|
85
|
+
|
86
|
+
Check the [examples](https://github.com/ElMassimo/js_from_routes/blob/master/spec/support/sample_app/app/javascript/Videos.vue) for ideas on how to [use it](https://github.com/ElMassimo/js_from_routes/blob/master/spec/support/sample_app/app/javascript/Videos.vue), and how you can [configure](https://github.com/ElMassimo/js_from_routes/blob/master/spec/support/sample_app/config/webpack/aliases.js#L11) Webpack to your convenience.
|
87
|
+
|
88
|
+
Read on to find out how to customize the generated code to suit your needs.
|
89
|
+
|
90
|
+
### Advanced Configuration 📖
|
91
|
+
|
92
|
+
Since all projects are different, it's very unlikely that the default settings
|
93
|
+
fulfill all your requirements.
|
94
|
+
|
95
|
+
The following [settings](https://github.com/ElMassimo/js_from_routes/blob/master/lib/js_from_routes/generator.rb#L77-L80) are available:
|
96
|
+
|
97
|
+
##### [`file_suffix`](https://github.com/ElMassimo/js_from_routes/blob/master/lib/js_from_routes/generator.rb#L77), default: `Requests.js`
|
98
|
+
|
99
|
+
This suffix is added by default to all generated files. You can modify it to
|
100
|
+
if you prefer a different convention.
|
101
|
+
|
102
|
+
##### [`helper_mappings`](https://github.com/ElMassimo/js_from_routes/blob/master/lib/js_from_routes/generator.rb#L80)
|
103
|
+
|
104
|
+
By default it maps `index` to `list` and `show` to `get`, which helps to make
|
105
|
+
the JS code read more natural.
|
106
|
+
|
107
|
+
##### [`output_folder`](https://github.com/ElMassimo/js_from_routes/blob/master/lib/js_from_routes/generator.rb#L78), default: `app/javascript/requests`
|
108
|
+
|
109
|
+
The directory where the generated files are created.
|
110
|
+
|
111
|
+
Tip: It's highly recommended to [add a webpack alias](https://github.com/ElMassimo/js_from_routes/blob/master/spec/support/sample_app/config/webpack/aliases.js#L11), to simplify [imports](https://github.com/ElMassimo/js_from_routes/blob/master/spec/support/sample_app/app/javascript/Videos.vue#2).
|
112
|
+
|
113
|
+
##### [`template_path`](https://github.com/ElMassimo/js_from_routes/blob/master/lib/js_from_routes/generator.rb#L79)
|
114
|
+
|
115
|
+
A [default template](https://github.com/ElMassimo/js_from_routes/blob/master/lib/js_from_routes/template.js.erb) is provided, but it makes assumptions about the [available](https://github.com/ElMassimo/js_from_routes/blob/master/spec/support/sample_app/app/javascript/services/ApiService.js#L17) [code](https://github.com/ElMassimo/js_from_routes/blob/master/spec/support/sample_app/app/javascript/helpers/UrlHelper.js#L28).
|
116
|
+
|
117
|
+
You will probably want to use a custom template, such as:
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
# config/initializers/js_from_routes.rb
|
121
|
+
JsFromRoutes.config do |config|
|
122
|
+
config.template = Rails.root.join('app', 'views', 'custom_js_from_routes.js.erb')
|
123
|
+
end
|
124
|
+
```
|
125
|
+
|
126
|
+
A `routes` variable will be available in the template, which will contain the
|
127
|
+
endpoints exported for a controller.
|
128
|
+
|
129
|
+
Each `route` exposes properties such as `verb` and `path`, please [check the
|
130
|
+
source code](https://github.com/ElMassimo/js_from_routes/blob/master/lib/js_from_routes/generator.rb#L34-L71) for details on the [API](https://github.com/ElMassimo/js_from_routes/blob/master/lib/js_from_routes/generator.rb#L34-L71).
|
131
|
+
|
132
|
+
### How does it work? ⚙️
|
133
|
+
|
134
|
+
By adding a hook to Rails' reload process in development, it's possible to
|
135
|
+
automatically generate files from routes when a route is added, modified, or removed.
|
136
|
+
|
137
|
+
In order to optimize file generation, the generated JS files are split by
|
138
|
+
controller, and add a cache key based on the routes to avoid rewriting the file
|
139
|
+
if the route definition hasn't changed.
|
140
|
+
|
141
|
+
When the Webpack development server is running, it detects when a new file is
|
142
|
+
generated, automatically triggering a new build, which can now use the generated
|
143
|
+
request methods or path helpers 😃
|
144
|
+
|
145
|
+
### Take this idea 💡
|
146
|
+
|
147
|
+
There are plenty of opportunities for automatic code generation, such as keeping
|
148
|
+
enums in sync between Ruby and JS.
|
149
|
+
|
150
|
+
Let me know if you come up with new or creative ways to use this technique 😃
|
151
|
+
|
152
|
+
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Splitting the generator file allows consumers to skip the Railtie if desired:
|
4
|
+
# - gem 'js_from_routes', require: false
|
5
|
+
# - require 'js_from_routes/generator'
|
6
|
+
require 'js_from_routes/generator'
|
7
|
+
require 'js_from_routes/railtie'
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'digest'
|
4
|
+
require 'erubi'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
# Public: Automatically generates JS for Rails routes with { export: true }.
|
8
|
+
# Generates one file per controller, and one function per route.
|
9
|
+
module JsFromRoutes
|
10
|
+
# Internal: Helper class used as a presenter for the routes template.
|
11
|
+
class Routes
|
12
|
+
attr_reader :routes
|
13
|
+
|
14
|
+
def initialize(routes, config)
|
15
|
+
@config = config
|
16
|
+
@routes = routes
|
17
|
+
.uniq { |route| route.requirements.fetch(:action) }
|
18
|
+
.map { |route| Route.new(route, config.helper_mappings) }
|
19
|
+
end
|
20
|
+
|
21
|
+
# Public: Used to check whether the file should be generated again, changes
|
22
|
+
# based on the configuration, and route definition.
|
23
|
+
def cache_key
|
24
|
+
Digest::MD5.hexdigest(routes.map(&:inspect).join + [File.read(@config.template_path), @config.helper_mappings.inspect].join)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Internal: By performing the evaluation here, we ensure only "routes" is
|
28
|
+
# exposed to the ERB template as a local variable.
|
29
|
+
def evaluate(compiled_template)
|
30
|
+
instance_eval(compiled_template)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Internal: A presenter for an individual Rails action.
|
35
|
+
class Route
|
36
|
+
def initialize(route, mappings = {})
|
37
|
+
@route, @mappings = route, mappings
|
38
|
+
end
|
39
|
+
|
40
|
+
# Public: Whether it should export only the path.
|
41
|
+
def path_only?
|
42
|
+
@route.defaults[:export] == :path_only
|
43
|
+
end
|
44
|
+
|
45
|
+
# Public: Whether it should export only the path.
|
46
|
+
def request_method?
|
47
|
+
!path_only?
|
48
|
+
end
|
49
|
+
|
50
|
+
# Public: The HTTP verb for the action. Example: 'patch'
|
51
|
+
def verb
|
52
|
+
@route.verb.downcase
|
53
|
+
end
|
54
|
+
|
55
|
+
# Public: The path for the action. Example: '/users/:id/edit'
|
56
|
+
def path
|
57
|
+
@route.path.spec.to_s.chomp('(.:format)')
|
58
|
+
end
|
59
|
+
|
60
|
+
# Public: The name of the JS helper for the action. Example: 'destroyAll'
|
61
|
+
def helper
|
62
|
+
action = @route.requirements.fetch(:action).camelize(:lower)
|
63
|
+
name = @mappings.fetch(action, action)
|
64
|
+
path_only? ? "#{ name }Path" : name
|
65
|
+
end
|
66
|
+
|
67
|
+
# Internal: Useful as a cache key for the route, and for debugging purposes.
|
68
|
+
def inspect
|
69
|
+
"#{ verb } #{ helper } #{ path }"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class << self
|
74
|
+
# Public: Configuration of the code generator.
|
75
|
+
def config
|
76
|
+
@config ||= OpenStruct.new(
|
77
|
+
file_suffix: 'Requests.js',
|
78
|
+
output_folder: ::Rails.root&.join('app', 'javascript', 'requests'),
|
79
|
+
template_path: File.expand_path('template.js.erb', __dir__),
|
80
|
+
helper_mappings: { 'index' => 'list', 'show' => 'get' },
|
81
|
+
)
|
82
|
+
yield(@config) if block_given?
|
83
|
+
@config
|
84
|
+
end
|
85
|
+
|
86
|
+
# Public: Generates code for the specified routes with { export: true }.
|
87
|
+
def generate!(app_or_routes = Rails.application)
|
88
|
+
raise ArgumentError, 'A Rails app must be defined, or you must specify a custom `output_folder`' if config.output_folder.blank?
|
89
|
+
rails_routes = app_or_routes.is_a?(::Rails::Engine) ? app_or_routes.routes.routes : app_or_routes
|
90
|
+
@compiled_template = nil # Clear on every code reload in case the template changed.
|
91
|
+
exported_routes_by_controller(rails_routes).each do |controller, controller_routes|
|
92
|
+
routes = Routes.new(controller_routes, config)
|
93
|
+
write_if_changed(filename_for(controller), routes.cache_key) { render_template(routes) }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
# Internal: Returns exported routes grouped by controller name.
|
100
|
+
def exported_routes_by_controller(routes)
|
101
|
+
routes.select { |route|
|
102
|
+
route.defaults.fetch(:export, false)
|
103
|
+
}.group_by { |route|
|
104
|
+
route.requirements.fetch(:controller)
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
# Internal: Name of the JS file with helpers for the the given controller.
|
109
|
+
def filename_for(controller)
|
110
|
+
config.output_folder.join("#{ controller.camelize }#{ config.file_suffix }".tr_s(':', '/'))
|
111
|
+
end
|
112
|
+
|
113
|
+
# Internal: Returns a String with the JS generated for a controller's routes.
|
114
|
+
def render_template(routes)
|
115
|
+
routes.evaluate(compiled_template)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Internal: Returns the compiled ERB to generate JS from a set of routes.
|
119
|
+
def compiled_template
|
120
|
+
@compiled_template ||= begin
|
121
|
+
template = File.read(config.template_path)
|
122
|
+
Erubi::Engine.new(template, filename: config.template_path).src
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Internal: Writes if the file does not exist or the cache key has changed.
|
127
|
+
# The cache strategy consists of a comment on the first line of the file.
|
128
|
+
#
|
129
|
+
# Yields to receive the rendered file content when it needs to.
|
130
|
+
def write_if_changed(name, cache_key)
|
131
|
+
FileUtils.mkdir_p(name.dirname)
|
132
|
+
cache_key_comment = "// JsFromRoutes CacheKey #{ cache_key }\n"
|
133
|
+
File.open(name, 'a+') { |file|
|
134
|
+
if file.gets != cache_key_comment
|
135
|
+
file.truncate(0)
|
136
|
+
file.write(cache_key_comment)
|
137
|
+
file.write(yield)
|
138
|
+
end
|
139
|
+
}
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# NOTE: Not strictly required, but it helps to simplify the setup.
|
4
|
+
class JsFromRoutes::Railtie < Rails::Railtie
|
5
|
+
railtie_name :js_from_routes
|
6
|
+
|
7
|
+
if Rails.env.development?
|
8
|
+
# Allows to automatically trigger code generation after updating routes.
|
9
|
+
initializer 'js_from_routes.reloader' do |app|
|
10
|
+
app.config.to_prepare do
|
11
|
+
JsFromRoutes.generate!(app)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Suitable when triggering code generation manually.
|
17
|
+
rake_tasks do |app|
|
18
|
+
namespace :js_from_routes do
|
19
|
+
desc 'Generates JavaScript files from Rails routes, one file per controller, and one function per route.'
|
20
|
+
task generate: :environment do
|
21
|
+
JsFromRoutes.generate!(app)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'support/sample_app/config/application'
|
2
|
+
require 'support/sample_app/config/routes'
|
3
|
+
|
4
|
+
|
5
|
+
describe JsFromRoutes do
|
6
|
+
ORIGINAL_TEMPLATE_PATH = JsFromRoutes.config.template_path
|
7
|
+
|
8
|
+
let(:output_dir) { Pathname.new File.expand_path('../support/generated', __dir__) }
|
9
|
+
let(:sample_dir) { Rails.root.join('app', 'javascript', 'requests') }
|
10
|
+
let(:different_template_path) { File.expand_path('../support/different_template.js.erb', __dir__) }
|
11
|
+
let(:controllers_with_exported_routes) { %w[Comments UserPreferences VideoClips] }
|
12
|
+
|
13
|
+
def file_for(dir, name)
|
14
|
+
dir.join("#{ name }Requests.js")
|
15
|
+
end
|
16
|
+
|
17
|
+
def sample_file_for(name)
|
18
|
+
file_for(sample_dir, name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def output_file_for(name)
|
22
|
+
file_for(output_dir, name)
|
23
|
+
end
|
24
|
+
|
25
|
+
before do
|
26
|
+
# Sanity checks
|
27
|
+
expect(sample_dir.exist?).to eq true
|
28
|
+
expect(Rails.application.routes.routes).to be_present
|
29
|
+
|
30
|
+
# Remove directory from a previous test run.
|
31
|
+
FileUtils.remove_dir(output_dir) rescue nil
|
32
|
+
|
33
|
+
# Change the configuration to use a different directory.
|
34
|
+
JsFromRoutes.config do |config|
|
35
|
+
config.output_folder = output_dir
|
36
|
+
config.template_path = ORIGINAL_TEMPLATE_PATH
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# NOTE: We do a manual snapshot test for now, more tests coming in the future.
|
41
|
+
it 'should generate the files as expected' do
|
42
|
+
expect(JsFromRoutes).to receive(:render_template).exactly(3).times.and_call_original
|
43
|
+
JsFromRoutes.generate!
|
44
|
+
|
45
|
+
# It does not generate routes that don't have `export: true`.
|
46
|
+
expect(output_file_for('Welcome').exist?).to eq false
|
47
|
+
|
48
|
+
# It generates one file per controller with exported routes.
|
49
|
+
controllers_with_exported_routes.each do |file_name|
|
50
|
+
expect(output_file_for(file_name).read).to eq sample_file_for(file_name).read
|
51
|
+
end
|
52
|
+
|
53
|
+
# It detects changes to the template, and regenerates the files.
|
54
|
+
JsFromRoutes.config do |config|
|
55
|
+
config.template_path = different_template_path
|
56
|
+
end
|
57
|
+
expect(JsFromRoutes).to receive(:render_template).exactly(3).times.and_call_original
|
58
|
+
JsFromRoutes.generate!
|
59
|
+
|
60
|
+
# These files should no longer match the sample ones.
|
61
|
+
controllers_with_exported_routes.each do |file_name|
|
62
|
+
expect(output_file_for(file_name).read).not_to eq sample_file_for(file_name).read
|
63
|
+
end
|
64
|
+
|
65
|
+
# It should not rewrite the files if the cache key has not changed.
|
66
|
+
expect(JsFromRoutes).not_to receive(:render_template)
|
67
|
+
JsFromRoutes.generate!
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should have a rake task available' do
|
71
|
+
Rails.application.load_tasks
|
72
|
+
expect(JsFromRoutes).to receive(:render_template).exactly(3).times
|
73
|
+
expect { Rake::Task['js_from_routes:generate'].invoke }.not_to raise_error
|
74
|
+
end
|
75
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative 'boot'
|
2
|
+
|
3
|
+
require "action_controller/railtie"
|
4
|
+
require "sprockets/railtie"
|
5
|
+
|
6
|
+
# Require the gems listed in Gemfile, including any gems
|
7
|
+
# you've limited to :test, :development, or :production.
|
8
|
+
Bundler.require(*Rails.groups)
|
9
|
+
|
10
|
+
module SampleApp
|
11
|
+
class Application < Rails::Application
|
12
|
+
# Initialize configuration defaults for originally generated Rails version.
|
13
|
+
config.load_defaults 6.0
|
14
|
+
|
15
|
+
# Settings in config/environments/* take precedence over those specified here.
|
16
|
+
# Application configuration can go into files in config/initializers
|
17
|
+
# -- all .rb files in that directory are automatically loaded after loading
|
18
|
+
# the framework and any gems in your application.
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
Rails.application.configure do
|
2
|
+
# Settings specified here will take precedence over those in config/application.rb.
|
3
|
+
|
4
|
+
# In the development environment your application's code is reloaded on
|
5
|
+
# every request. This slows down response time but is perfect for development
|
6
|
+
# since you don't have to restart the web server when you make code changes.
|
7
|
+
config.cache_classes = false
|
8
|
+
|
9
|
+
# Do not eager load code on boot.
|
10
|
+
config.eager_load = false
|
11
|
+
|
12
|
+
# Show full error reports.
|
13
|
+
config.consider_all_requests_local = true
|
14
|
+
|
15
|
+
# Store uploaded files on the local file system (see config/storage.yml for options).
|
16
|
+
# Print deprecation notices to the Rails logger.
|
17
|
+
config.active_support.deprecation = :log
|
18
|
+
|
19
|
+
# Debug mode disables concatenation and preprocessing of assets.
|
20
|
+
# This option may cause significant delays in view rendering with a large
|
21
|
+
# number of complex assets.
|
22
|
+
config.assets.debug = true
|
23
|
+
|
24
|
+
# Suppress logger output for asset requests.
|
25
|
+
config.assets.quiet = true
|
26
|
+
|
27
|
+
# Raises error for missing translations.
|
28
|
+
# config.action_view.raise_on_missing_translations = true
|
29
|
+
|
30
|
+
# Use an evented file watcher to asynchronously detect changes in source code,
|
31
|
+
# routes, locales, etc. This feature depends on the listen gem.
|
32
|
+
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
|
33
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# Version of your assets, change this if you want to expire all your assets.
|
4
|
+
Rails.application.config.assets.version = '1.0'
|
5
|
+
|
6
|
+
# Add additional assets to the asset load path.
|
7
|
+
# Rails.application.config.assets.paths << Emoji.images_path
|
8
|
+
# Add Yarn node_modules folder to the asset load path.
|
9
|
+
Rails.application.config.assets.paths << Rails.root.join('node_modules')
|
10
|
+
|
11
|
+
# Precompile additional assets.
|
12
|
+
# application.js, application.css, and all non-JS/CSS in the app/assets
|
13
|
+
# folder are already added.
|
14
|
+
# Rails.application.config.assets.precompile += %w( admin.js admin.css )
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
|
4
|
+
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
|
5
|
+
|
6
|
+
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
|
7
|
+
# Rails.backtrace_cleaner.remove_silencers!
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# Define an application-wide content security policy
|
4
|
+
# For further information see the following documentation
|
5
|
+
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
|
6
|
+
|
7
|
+
# Rails.application.config.content_security_policy do |policy|
|
8
|
+
# policy.default_src :self, :https
|
9
|
+
# policy.font_src :self, :https, :data
|
10
|
+
# policy.img_src :self, :https, :data
|
11
|
+
# policy.object_src :none
|
12
|
+
# policy.script_src :self, :https
|
13
|
+
# policy.style_src :self, :https
|
14
|
+
# # If you are using webpack-dev-server then specify webpack-dev-server host
|
15
|
+
# policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development?
|
16
|
+
|
17
|
+
# # Specify URI for violation reports
|
18
|
+
# # policy.report_uri "/csp-violation-report-endpoint"
|
19
|
+
# end
|
20
|
+
|
21
|
+
# If you are using UJS then enable automatic nonce generation
|
22
|
+
# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
|
23
|
+
|
24
|
+
# Set the nonce only to specific directives
|
25
|
+
# Rails.application.config.content_security_policy_nonce_directives = %w(script-src)
|
26
|
+
|
27
|
+
# Report CSP violations to a specified URI
|
28
|
+
# For further information see the following documentation:
|
29
|
+
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
|
30
|
+
# Rails.application.config.content_security_policy_report_only = true
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# Add new inflection rules using the following format. Inflections
|
4
|
+
# are locale specific, and you may define rules for as many different
|
5
|
+
# locales as you wish. All of these examples are active by default:
|
6
|
+
# ActiveSupport::Inflector.inflections(:en) do |inflect|
|
7
|
+
# inflect.plural /^(ox)$/i, '\1en'
|
8
|
+
# inflect.singular /^(ox)en/i, '\1'
|
9
|
+
# inflect.irregular 'person', 'people'
|
10
|
+
# inflect.uncountable %w( fish sheep )
|
11
|
+
# end
|
12
|
+
|
13
|
+
# These inflection rules are supported but not enabled by default:
|
14
|
+
# ActiveSupport::Inflector.inflections(:en) do |inflect|
|
15
|
+
# inflect.acronym 'RESTful'
|
16
|
+
# end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Be sure to restart your server when you modify this file.
|
2
|
+
|
3
|
+
# This file contains settings for ActionController::ParamsWrapper which
|
4
|
+
# is enabled by default.
|
5
|
+
|
6
|
+
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
|
7
|
+
ActiveSupport.on_load(:action_controller) do
|
8
|
+
wrap_parameters format: [:json]
|
9
|
+
end
|
10
|
+
|
11
|
+
# To enable root element in JSON for ActiveRecord objects.
|
12
|
+
# ActiveSupport.on_load(:active_record) do
|
13
|
+
# self.include_root_in_json = true
|
14
|
+
# end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Puma can serve each request in a thread from an internal thread pool.
|
2
|
+
# The `threads` method setting takes two numbers: a minimum and maximum.
|
3
|
+
# Any libraries that use thread pools should be configured to match
|
4
|
+
# the maximum value specified for Puma. Default is set to 5 threads for minimum
|
5
|
+
# and maximum; this matches the default thread size of Active Record.
|
6
|
+
#
|
7
|
+
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
|
8
|
+
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
|
9
|
+
threads min_threads_count, max_threads_count
|
10
|
+
|
11
|
+
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
|
12
|
+
#
|
13
|
+
port ENV.fetch("PORT") { 3000 }
|
14
|
+
|
15
|
+
# Specifies the `environment` that Puma will run in.
|
16
|
+
#
|
17
|
+
environment ENV.fetch("RAILS_ENV") { "development" }
|
18
|
+
|
19
|
+
# Specifies the `pidfile` that Puma will use.
|
20
|
+
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
|
21
|
+
|
22
|
+
# Specifies the number of `workers` to boot in clustered mode.
|
23
|
+
# Workers are forked web server processes. If using threads and workers together
|
24
|
+
# the concurrency of the application would be max `threads` * `workers`.
|
25
|
+
# Workers do not work on JRuby or Windows (both of which do not support
|
26
|
+
# processes).
|
27
|
+
#
|
28
|
+
# workers ENV.fetch("WEB_CONCURRENCY") { 2 }
|
29
|
+
|
30
|
+
# Use the `preload_app!` method when specifying a `workers` number.
|
31
|
+
# This directive tells Puma to first boot the application and load code
|
32
|
+
# before forking the application. This takes advantage of Copy On Write
|
33
|
+
# process behavior so workers use less memory.
|
34
|
+
#
|
35
|
+
# preload_app!
|
36
|
+
|
37
|
+
# Allow puma to be restarted by `rails restart` command.
|
38
|
+
plugin :tmp_restart
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
root to: 'welcome#home'
|
3
|
+
|
4
|
+
resources :welcome
|
5
|
+
|
6
|
+
resources :video_clips, only: [:new, :edit, :create, :update, :destroy], export: true do
|
7
|
+
get :download, on: :member, export: :path_only
|
8
|
+
patch :add_to_playlist, on: :member
|
9
|
+
patch :remove_from_playlist, on: :member
|
10
|
+
get :trending, on: :collection
|
11
|
+
get '/thumbnail/:thumbnail_id', as: :thumbnail, action: :thumbnail, on: :member
|
12
|
+
|
13
|
+
resources :comments, only: [:show, :index], shallow: true, export: true
|
14
|
+
end
|
15
|
+
|
16
|
+
resources :user_preferences, only: [], export: true do
|
17
|
+
patch :switch_to_classic_navbar, on: :collection
|
18
|
+
get :switch_to_beta_navbar, on: :collection, export: false
|
19
|
+
get '/switch_to_classic/:page', action: :switch_to_classic, on: :collection, export: :path_only
|
20
|
+
get '/switch_to_beta/:page', action: :switch_to_beta, on: :collection, as: :switch_to_beta_page, export: :path_only
|
21
|
+
end
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: js_from_routes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Máximo Mussini
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-06-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: railties
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: js_from_routes helps you by automatically generating path and API helpers
|
56
|
+
from Rails route definitions, allowing you to save development effort and focus
|
57
|
+
on the things that matter.
|
58
|
+
email:
|
59
|
+
- maximomussini@gmail.com
|
60
|
+
executables: []
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files:
|
63
|
+
- README.md
|
64
|
+
files:
|
65
|
+
- README.md
|
66
|
+
- lib/js_from_routes.rb
|
67
|
+
- lib/js_from_routes/generator.rb
|
68
|
+
- lib/js_from_routes/railtie.rb
|
69
|
+
- lib/js_from_routes/version.rb
|
70
|
+
- spec/js_from_routes/js_from_routes_spec.rb
|
71
|
+
- spec/spec_helper.rb
|
72
|
+
- spec/support/sample_app/app/controllers/application_controller.rb
|
73
|
+
- spec/support/sample_app/app/controllers/comments_controller.rb
|
74
|
+
- spec/support/sample_app/app/controllers/user_preferences_controller.rb
|
75
|
+
- spec/support/sample_app/app/controllers/video_clips_controller.rb
|
76
|
+
- spec/support/sample_app/app/controllers/welcome_controller.rb
|
77
|
+
- spec/support/sample_app/app/mailers/application_mailer.rb
|
78
|
+
- spec/support/sample_app/config/application.rb
|
79
|
+
- spec/support/sample_app/config/boot.rb
|
80
|
+
- spec/support/sample_app/config/environment.rb
|
81
|
+
- spec/support/sample_app/config/environments/development.rb
|
82
|
+
- spec/support/sample_app/config/initializers/application_controller_renderer.rb
|
83
|
+
- spec/support/sample_app/config/initializers/assets.rb
|
84
|
+
- spec/support/sample_app/config/initializers/backtrace_silencers.rb
|
85
|
+
- spec/support/sample_app/config/initializers/content_security_policy.rb
|
86
|
+
- spec/support/sample_app/config/initializers/cookies_serializer.rb
|
87
|
+
- spec/support/sample_app/config/initializers/filter_parameter_logging.rb
|
88
|
+
- spec/support/sample_app/config/initializers/inflections.rb
|
89
|
+
- spec/support/sample_app/config/initializers/mime_types.rb
|
90
|
+
- spec/support/sample_app/config/initializers/wrap_parameters.rb
|
91
|
+
- spec/support/sample_app/config/puma.rb
|
92
|
+
- spec/support/sample_app/config/routes.rb
|
93
|
+
- spec/support/sample_app/node_modules/node-sass/src/libsass/extconf.rb
|
94
|
+
homepage: https://github.com/ElMassimo/js_from_routes
|
95
|
+
licenses:
|
96
|
+
- MIT
|
97
|
+
metadata: {}
|
98
|
+
post_install_message:
|
99
|
+
rdoc_options: []
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
requirements: []
|
113
|
+
rubygems_version: 3.1.2
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: Generate JS automatically from Rails routes.
|
117
|
+
test_files:
|
118
|
+
- spec/spec_helper.rb
|
119
|
+
- spec/js_from_routes/js_from_routes_spec.rb
|
120
|
+
- spec/support/sample_app/app/mailers/application_mailer.rb
|
121
|
+
- spec/support/sample_app/app/controllers/video_clips_controller.rb
|
122
|
+
- spec/support/sample_app/app/controllers/application_controller.rb
|
123
|
+
- spec/support/sample_app/app/controllers/comments_controller.rb
|
124
|
+
- spec/support/sample_app/app/controllers/welcome_controller.rb
|
125
|
+
- spec/support/sample_app/app/controllers/user_preferences_controller.rb
|
126
|
+
- spec/support/sample_app/config/routes.rb
|
127
|
+
- spec/support/sample_app/config/environments/development.rb
|
128
|
+
- spec/support/sample_app/config/environment.rb
|
129
|
+
- spec/support/sample_app/config/application.rb
|
130
|
+
- spec/support/sample_app/config/puma.rb
|
131
|
+
- spec/support/sample_app/config/boot.rb
|
132
|
+
- spec/support/sample_app/config/initializers/application_controller_renderer.rb
|
133
|
+
- spec/support/sample_app/config/initializers/backtrace_silencers.rb
|
134
|
+
- spec/support/sample_app/config/initializers/mime_types.rb
|
135
|
+
- spec/support/sample_app/config/initializers/filter_parameter_logging.rb
|
136
|
+
- spec/support/sample_app/config/initializers/wrap_parameters.rb
|
137
|
+
- spec/support/sample_app/config/initializers/assets.rb
|
138
|
+
- spec/support/sample_app/config/initializers/cookies_serializer.rb
|
139
|
+
- spec/support/sample_app/config/initializers/content_security_policy.rb
|
140
|
+
- spec/support/sample_app/config/initializers/inflections.rb
|
141
|
+
- spec/support/sample_app/node_modules/node-sass/src/libsass/extconf.rb
|