railbus 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3a4d4f90743b019f021dce043615b79204496078835955c549aee7e31238aaad
4
+ data.tar.gz: d0d414564db34c8c3a12ee40a060333f208da3443754fba9af7c4943d3ce3843
5
+ SHA512:
6
+ metadata.gz: ffaadfde8d0fc1367f75a6b4ddd49d6bf399269ccb6e92fde68d5b712fb21f3fc657a952e4129739ef40dabf34f471e03f0a0e69ce40d8596806d6b220c7bfc4
7
+ data.tar.gz: 2e6b62c58abfa3fe253d387eb3d4d863998784b1f11734e8fa133db09c5493b85705c02b4106bc4a022c17fbbae5d99ef7d2281a7cdc9323d93e78cb959db4c3
@@ -0,0 +1,33 @@
1
+ root = true
2
+
3
+ [*.{rb,md,editorconfig,js,rake,erb}]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ indent_style = space
8
+ indent_size = 2
9
+ max_line_length = 80
10
+ trim_trailing_whitespace = true
11
+
12
+ [{Gemfile*,Rakefile,.git*,.rspec}]
13
+ charset = utf-8
14
+ end_of_line = lf
15
+ insert_final_newline = true
16
+ indent_style = space
17
+ indent_size = 2
18
+ max_line_length = 80
19
+ trim_trailing_whitespace = true
20
+
21
+ [*.md]
22
+ indent_size = unset
23
+ max_line_length = unset
24
+ trim_trailing_whitespace = false
25
+
26
+ [{{.git,bin,tmp,vendor}/**,*.lock}]
27
+ charset = unset
28
+ end_of_line = unset
29
+ insert_final_newline = unset
30
+ indent_style = unset
31
+ indent_size = unset
32
+ max_line_length = unset
33
+ trim_trailing_whitespace = unset
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.6.5
6
+ before_install: gem install bundler -v 2.1.4
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in railbus.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Evgeniy Nochevnov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,227 @@
1
+ # Railbus
2
+
3
+ Do you want to use autogenerated set of Rails application routes in your JavaScript files?
4
+
5
+ Do you want to make requests to your routes from JS with human-readable names like `create_news`, `update_message`?
6
+
7
+ Here comes Railbus to you.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'railbus'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle install
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install railbus
24
+
25
+ To use it with Webpack, create `*.js.erb` file in `app/javascript`
26
+ (e.g. `lib/routes.js.erb`):
27
+
28
+ ```erb
29
+ /* rails-erb-loader-dependencies ../config/routes */
30
+ <%= Railbus.generate %>
31
+ ```
32
+
33
+ And the last step, require this file in your `.js` files where you want to use application routes.
34
+
35
+ ```js
36
+ import Routes from 'lib/routes'
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ In short:
42
+
43
+ 1. See output of `rails routes`, it includes route names. You may use these names in JS as functions for XHR requests.
44
+ 2. Append `_path` to a route name to get its URL.
45
+
46
+ Route names in JS depend on route names in Rails:
47
+
48
+ Action name | HTTP method | Request function | Path function
49
+ ------------|-------------|------------------------|----------------------------
50
+ index | GET | {plural_name} | {plural_name}_path
51
+ show | GET | {singular_name} | {singular_name}_path
52
+ new | GET | new_{singular_name} | new_{singular_name}_path
53
+ edit | GET | edit_{singular_name} | edit_{singular_name}_path
54
+ create | POST | create_{singular_name} | create_{singular_name}_path
55
+ update | PUT/PATCH | update_{singular_name} | update_{singular_name}_path
56
+ destroy | DELETE | delete_{singular_name} | delete_{singular_name}_path
57
+
58
+ ### Functions' arguments
59
+
60
+ Here `String or Number, ...` represents values used in paths, e.g.
61
+ `:id`, `:category_id` (zero, one or more params).
62
+
63
+ And `...path_params` means hash-like object with values for paths, e.g.
64
+ `{id: 123, category_id: 56}` (zero, one or more params).
65
+
66
+ `data` means request body (payload), it can be hash-like object, `FormData` and so on, its allowed types depend on XHR library.
67
+
68
+ All arguments are optional.
69
+
70
+ ```js
71
+ // Request `index`, `show`, `new`, `edit`, `destroy` actions.
72
+ ({format: String, ...path_params, ...url_options})
73
+ // Or:
74
+ (String or Number, ..., {format: String, ...url_options})
75
+
76
+ // Request `create` and `update` actions.
77
+ ({format: String, ...path_params, ...url_options}, data)
78
+ // Or:
79
+ (String or Number, ..., {format: String, ...url_options}, data)
80
+
81
+ // Get path for any action (does not include query string starting with '?').
82
+ ({format: String, ...path_params})
83
+ // Or:
84
+ (String or Number, ..., {format: String})
85
+ ```
86
+
87
+ ### Configuration
88
+
89
+ By default Railbus generates functions for all routes defined
90
+ in `Rails.application` and these functions use `axios`. You may change it:
91
+
92
+ ```js
93
+ <%=
94
+ Railbus.generate(
95
+ # Here `YourApp::Engine` inherits `Rails::Engine`.
96
+ # Default: `Rails.application`.
97
+ app: YourApp::Engine,
98
+
99
+ # 'axios' or the name of function defined or imported in this file.
100
+ # Default: 'axios'.
101
+ client: 'request_api',
102
+
103
+ # Include only these route paths that start with '/api'.
104
+ # Empty array: include all routes (default).
105
+ include: [%r{^/api}],
106
+
107
+ # Exclude all route paths matching regexpes.
108
+ # Empty array: do not exclude any routes (default).
109
+ exclude: [/edit|new/]
110
+ )
111
+ %>
112
+
113
+ import axios from 'axios';
114
+ const axios_api = axios.create({
115
+ baseURL: `${document.location.origin}/api/`
116
+ })
117
+
118
+ function request_api(route, params) {
119
+ return axios_api.request({
120
+ url: params.path,
121
+ method: route.verb,
122
+ params: params.url_options,
123
+ data: params.data
124
+ })
125
+ }
126
+ ```
127
+
128
+ ### Examples
129
+
130
+ Let's take these routes as an example:
131
+
132
+ ```ruby
133
+ resources :news do
134
+ resources :images, only: %w[index show create update destroy]
135
+ end
136
+ resources :messages, only: %w[new create]
137
+ namespace :my do
138
+ resources :favourites, only: %w[index show create update destroy]
139
+ end
140
+ ```
141
+
142
+ To make XHR requests with promises you may do this in JS
143
+ ([axios](https://github.com/axios/axios) required):
144
+
145
+ ```js
146
+ import Routes from 'lib/routes'
147
+
148
+ // Request all favourites and print to console. Note: using namespace `my`.
149
+ // It will call `My::FavouritesController#index`.
150
+ // Path: '/my/favourites'.
151
+ Routes.my_favourites().then(response => console.log(response.data))
152
+
153
+ // Request all news and print to console.
154
+ // String `index` appended to distinguish `index` and `show` actions.
155
+ // It will call `NewsController#index`.
156
+ // Path: '/news'.
157
+ Routes.news_index().then(response => console.log(response.data))
158
+
159
+ // Request all news filtered by date, and print to console.
160
+ // `NewsController#index` with param `date` in query string (GET).
161
+ // Path: '/news' with query string '?date=2020-12-31'.
162
+ Routes.news_index({date: '2020-12-31'}).then(response => console.log(response.data))
163
+
164
+ // Request one news and print to console.
165
+ // `NewsController#show` with param `id` = 327 (GET).
166
+ // Path: '/news/327'.
167
+ Routes.news(327).then(response => console.log(response.data))
168
+ // Or
169
+ Routes.news({id: 327}).then(response => console.log(response.data))
170
+
171
+ // Specify format (for example, '.json').
172
+ // `NewsController#show` with param `id` = 327 (GET) and `format` = 'json'.
173
+ // Path: '/news/327.json'.
174
+ Routes.news(327, {format: 'json'}).then(response => console.log(response.data))
175
+ // Or
176
+ Routes.news({id: 327, format: 'json'}).then(response => console.log(response.data))
177
+
178
+ // Create news with given title.
179
+ // `NewsController#create` with param `title` (POST).
180
+ Routes.create_news({title: 'Bears showed up in Tomsk'}).then(response => console.log(response.data))
181
+
182
+ // Create message with given title. Note: `message`, singular form.
183
+ // `MessagesController#create` with params `body`, `to` (POST).
184
+ Routes.create_message({body: 'Fantastic!', to: 23}).then(response => console.log(response.data))
185
+
186
+ // Create message with given title. Note: using namespace `my`.
187
+ // `My::FavouritesController#create` with param `url` (POST).
188
+ Routes.create_my_favourite({url: 'https://best.site'}).then(response => console.log(response.data))
189
+
190
+ // Attach an image to the news.
191
+ // `ImageController#create` with param `news_id` = 41 (GET), `blob` (POST).
192
+ Routes.create_news_image(41, {blob: file})
193
+
194
+ // Get URL for `create` action.
195
+ Routes.create_my_favourite_path() // => 'my/favourites'
196
+ ```
197
+
198
+ ## Development
199
+
200
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
201
+
202
+ To install this gem onto your local machine, run `bundle exec rake install`.
203
+
204
+ TODO:
205
+
206
+ - Support [fetch](https://developer.mozilla.org/ru/docs/Web/API/Fetch_API/Using_Fetch)
207
+ - Tests
208
+
209
+ ## Contributing
210
+
211
+ Bug reports and pull requests are welcome on GitHub at [github.com/crosspath/railbus](https://github.com/crosspath/railbus).
212
+
213
+ Please do not change version number in pull requests.
214
+
215
+ ## Alternative solutions
216
+
217
+ 1. [rswag](https://github.com/rswag/rswag) +
218
+ [swagger-js](https://github.com/swagger-api/swagger-js) +
219
+ your integration specs (tests)
220
+ 2. [railsware/js-routes](https://github.com/railsware/js-routes)
221
+ 3. [mtrpcic/js-routes](https://github.com/mtrpcic/js-routes)
222
+ 4. [less-js-routes](https://github.com/stevenbristol/less-js-routes)
223
+ 5. [js_named_routes](https://github.com/jsierles/js_named_routes)
224
+
225
+ ## License
226
+
227
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "railbus"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,28 @@
1
+ require 'json'
2
+ require 'erubi'
3
+ require 'active_support'
4
+
5
+ require_relative 'railbus/version'
6
+ require_relative 'railbus/route_set'
7
+ require_relative 'railbus/route_set_presenter'
8
+
9
+ module Railbus
10
+ module_function
11
+
12
+ def generate(
13
+ app: Rails.application,
14
+ client: 'axios',
15
+ include: [],
16
+ exclude: []
17
+ )
18
+ route_set = RouteSet.new(app, include, exclude)
19
+ routes_json = Railbus::RouteSetPresenter.to_h(route_set).to_json
20
+
21
+ js_template = File.join(__dir__, 'railbus', 'templates', 'js.erb')
22
+ erb_engine = Erubi::Engine.new(File.read(js_template))
23
+
24
+ # Template uses `routes_json`, `client`
25
+ client = client.to_s
26
+ eval(erb_engine.src)
27
+ end
28
+ end
@@ -0,0 +1,114 @@
1
+ class Railbus::RouteSet
2
+ # Example:
3
+ # get, /users/:id, ['/users/', {a: 'id'}], ['id'], user
4
+ Route = Struct.new(:verb, :path, :parts, :required, :name)
5
+
6
+ %w[post patch put].each do |word|
7
+ Route.define_method("#{word}?") { verb == word }
8
+ end
9
+
10
+ MAP_NAMES = {
11
+ 'post' => 'create_',
12
+ 'put' => 'update_',
13
+ 'patch' => 'update_',
14
+ 'delete' => 'destroy_'
15
+ }
16
+
17
+ attr_reader :paths
18
+
19
+ def initialize(app, include, exclude)
20
+ @paths = add_route_names(paths_for_app(app, include, exclude))
21
+ end
22
+
23
+ private
24
+
25
+ def paths_for_app(app, include, exclude)
26
+ app.routes.set.routes.map do |route|
27
+ formatter = route.instance_variable_get(:@path_formatter)
28
+ route_parts = parts_combined(formatter.instance_variable_get(:@parts))
29
+
30
+ path = join_parts(route_parts)
31
+ next nil unless include_path?(path, include, exclude)
32
+
33
+ Route.new(
34
+ route.verb.downcase,
35
+ path,
36
+ route_parts,
37
+ required_params(route_parts),
38
+ route.name
39
+ )
40
+ end.compact
41
+ end
42
+
43
+ def parts_combined(parts)
44
+ parts.reduce([]) do |a, pt|
45
+ e = parts_element(pt)
46
+ next a if e.empty?
47
+ if a.empty?
48
+ a = [e]
49
+ elsif a[-1].respond_to?(:<<) && e.respond_to?(:<<)
50
+ # Both vars are strings -> concat them.
51
+ a[-1] << e
52
+ else
53
+ a << e
54
+ end
55
+ a
56
+ end
57
+ end
58
+
59
+ def parts_element(part)
60
+ if part.respond_to?(:name)
61
+ # Is a path parameter (e.g. `:id`).
62
+ {a: part.name}
63
+ else
64
+ # Is a `format` parameter -> skip it.
65
+ # Otherwise it is a string.
66
+ (part.respond_to?(:evaluate) ? '' : part).dup
67
+ end
68
+ end
69
+
70
+ def join_parts(route_parts)
71
+ route_parts.map { |x| x.respond_to?(:<<) ? x : ":#{x[:a]}" }.join
72
+ end
73
+
74
+ def required_params(route_parts)
75
+ route_parts.reject { |x| x.respond_to?(:<<) }.map { |x| x[:a] }
76
+ end
77
+
78
+ def include_path?(path, include, exclude)
79
+ return false if !include.empty? && include.none? { |re| path =~ re }
80
+ return false if exclude.any? { |re| path =~ re }
81
+ true
82
+ end
83
+
84
+ def add_route_names(paths)
85
+ paths.group_by(&:path).flat_map do |_, routes|
86
+ name = routes.find(&:name)&.name
87
+ if name
88
+ routes.reject!(&:patch?) if routes.find(&:put?)
89
+ routes.map do |route|
90
+ route.name ||= "#{MAP_NAMES[route.verb]}#{route_name(route, name)}"
91
+ route
92
+ end
93
+ else
94
+ []
95
+ end
96
+ end.uniq
97
+ end
98
+
99
+ def route_name(route, base_name)
100
+ if route.post?
101
+ route_name_for_create(base_name)
102
+ else
103
+ base_name
104
+ end
105
+ end
106
+
107
+ def route_name_for_create(base_name)
108
+ if base_name.end_with?('_index')
109
+ base_name.sub(/_index$/, '')
110
+ else
111
+ base_name.singularize
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,11 @@
1
+ module Railbus::RouteSetPresenter
2
+ module_function
3
+
4
+ def to_h(route_set)
5
+ result = {}
6
+ route_set.paths.each do |route|
7
+ result[route.name] = route.to_h
8
+ end
9
+ result
10
+ end
11
+ end
@@ -0,0 +1,92 @@
1
+ const routes = <%= routes_json.html_safe %>;
2
+
3
+ <% if client == 'axios' %>
4
+ import axios from 'axios'
5
+
6
+ function request(route, args) {
7
+ const params = build_request_options(route, args)
8
+ return axios.request({
9
+ url: params.path,
10
+ method: route.verb,
11
+ params: params.url_options,
12
+ data: params.data
13
+ })
14
+ }
15
+ <% else %>
16
+ function request(route, args) {
17
+ const params = build_request_options(route, args)
18
+ return <%= client %>(route, params)
19
+ }
20
+ <% end %>
21
+
22
+ const request_functions = Object.fromEntries(
23
+ Object.entries(routes).map(pair => {
24
+ const route = pair[1]
25
+ const func = (...args) => request(route, args)
26
+ return [pair[0], func]
27
+ })
28
+ )
29
+
30
+ const path_functions = Object.fromEntries(
31
+ Object.entries(routes).map(pair => {
32
+ const route = pair[1]
33
+ const func = (...args) => build_request_options(route, args).path
34
+ return [`${pair[0]}_path`, func]
35
+ })
36
+ )
37
+
38
+ export default Object.assign({}, request_functions, path_functions)
39
+
40
+ function split_args(route, args) {
41
+ const required_params = route.required
42
+ let path_params = {}, url_options = {}, data = {}
43
+ for (let index in args) {
44
+ const arg = args[index]
45
+ if (['string', 'number'].includes(typeof arg)) {
46
+ path_params[required_params[index]] = arg
47
+ } else {
48
+ break
49
+ }
50
+ }
51
+ let options = args[Object.keys(path_params).length]
52
+ data = args[Object.keys(path_params).length + 1]
53
+ if (typeof options !== 'object')
54
+ options = {}
55
+ if (typeof data !== 'object')
56
+ data = {}
57
+ for (let param of required_params) {
58
+ if (!(param in path_params)) {
59
+ if (param in options) {
60
+ path_params[param] = options[param]
61
+ } else {
62
+ throw new Error(required_param(route, param))
63
+ }
64
+ }
65
+ }
66
+ const format = presence(options.format)
67
+ const extracted = required_params.concat(['format'])
68
+ url_options = Object.fromEntries(
69
+ Object.entries(options).filter(pair => !extracted.includes(pair[0]))
70
+ )
71
+ return {path_params, format, url_options, data}
72
+ }
73
+
74
+ function presence(v) {
75
+ return (v != null && v !== '') ? v : null
76
+ }
77
+
78
+ function required_param(route, param) {
79
+ return `Cannot find "${param}" in passed URL options. `+
80
+ `This value is required for route "${route.name}" (${route.path}).`;
81
+ }
82
+
83
+ function build_request_options(route, args) {
84
+ const params = split_args(route, args)
85
+ let path = route.parts.
86
+ map(v => typeof v === 'string' ? v : params.path_params[v.a]).join('')
87
+ if (params.format)
88
+ path += `.${params.format}`
89
+ if (['get', 'delete'].includes(route.verb))
90
+ params.data = null
91
+ return {path: path, url_options: params.url_options, data: params.data}
92
+ }
@@ -0,0 +1,3 @@
1
+ module Railbus
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,34 @@
1
+ require_relative 'lib/railbus/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "railbus"
5
+ spec.version = Railbus::VERSION
6
+ spec.authors = ["Evgeniy Nochevnov"]
7
+
8
+ spec.summary = %q{Generate JS functions for XHR requests to Rails routes}
9
+ # spec.description = %q{TODO: Write a longer description or delete this line.}
10
+ spec.homepage = "https://github.com/crosspath/railbus"
11
+ spec.license = "MIT"
12
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
13
+
14
+ spec.add_dependency 'activesupport'
15
+ spec.add_dependency 'erubi'
16
+
17
+ spec.add_development_dependency 'rake'
18
+ # spec.add_development_dependency 'rspec', '>= 3'
19
+
20
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
21
+
22
+ spec.metadata["homepage_uri"] = spec.homepage
23
+ spec.metadata["source_code_uri"] = "https://github.com/crosspath/railbus"
24
+ # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
25
+
26
+ # Specify which files should be added to the gem when it is released.
27
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
28
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
29
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
30
+ end
31
+ spec.bindir = "exe"
32
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
33
+ spec.require_paths = ["lib"]
34
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: railbus
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Evgeniy Nochevnov
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-07-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
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: erubi
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
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:
56
+ email:
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - ".editorconfig"
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - ".travis.yml"
65
+ - Gemfile
66
+ - LICENSE
67
+ - README.md
68
+ - Rakefile
69
+ - bin/console
70
+ - bin/setup
71
+ - lib/railbus.rb
72
+ - lib/railbus/route_set.rb
73
+ - lib/railbus/route_set_presenter.rb
74
+ - lib/railbus/templates/js.erb
75
+ - lib/railbus/version.rb
76
+ - railbus.gemspec
77
+ homepage: https://github.com/crosspath/railbus
78
+ licenses:
79
+ - MIT
80
+ metadata:
81
+ homepage_uri: https://github.com/crosspath/railbus
82
+ source_code_uri: https://github.com/crosspath/railbus
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: 2.3.0
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubygems_version: 3.0.3
99
+ signing_key:
100
+ specification_version: 4
101
+ summary: Generate JS functions for XHR requests to Rails routes
102
+ test_files: []