railbus 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eca04d46928b46af6ee37969c8cd9e34ffa535ae8295b9a3efba843c4a1fbe32
4
- data.tar.gz: a708f98d5b39524baf0888bd96f458df8a6dbc63e97a1827447fd2423ffeb03a
3
+ metadata.gz: c9c2e34aa14ab37ae14293ac159f7c1d8850f36ee5063bc373ff63c3d26fea36
4
+ data.tar.gz: a2573f5dd914ed8a0f8756d5905696f4e770387d8f068f20b615b901b37397cf
5
5
  SHA512:
6
- metadata.gz: b3f9a587e3d6658f6cacda733db67d37af4d8b2d8316e9d63f11f0a0899e54ad24b2d124a4f8750536786a923faa0200dd6a1c3025f926230d2257a8f3a6cca3
7
- data.tar.gz: 35964ef3fd6e599cfca9aee232abc332d9ebf86ba072b1efde5fd5ad43aef1ad5c8670f268bef98ff3f4d2796cb25091a14357605bbc70647691ae7cba3f1001
6
+ metadata.gz: 2f058f3bbf84e63f96b5a797c7083e0aacb4c1a1ad7f40c19553c885dc28e223397976a57badfc95a77078bb5a41b2f5c8ce2335b273946d4763769b515a4728
7
+ data.tar.gz: 115f416c92960e08fd12dec4f2ad4f8eb76fb93f9b76450071546b8d5b3f9b91f2a5dffe61f842fb8f9a2d805dd684fba0e70a79549050ac4db91a5e0ce026c1
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ # Version 0.2.0
4
+
5
+ 1. Extract Axios-related functionality to NPM package 'yambus-axios'.
6
+ 2. Add support for `fetch` with NPM package 'yambus-fetch'.
7
+ 3. Custom request function now can add options before performing request
8
+ (`set_options` in `Railbus.generate`). Also it may be useful for logging
9
+ requests.
10
+ 4. Enriched support for multiple Rails engines. Now Railbus autodetects endpoint
11
+ for mounted engines for generating correct paths.
12
+
3
13
  # Version 0.1.2
4
14
 
5
15
  Extract JavaScript generators to NPM package called 'yambus'.
data/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # Railbus
2
2
 
3
- Do you want to use autogenerated set of Rails application routes in your JavaScript files?
3
+ Do you want to use autogenerated set of Rails application routes in your
4
+ JavaScript files?
4
5
 
5
- Do you want to make requests to your routes from JS with human-readable names like `create_news`, `update_message`?
6
+ Do you want to make requests to your routes from JS with human-readable names
7
+ like `create_news`, `update_message`?
6
8
 
7
9
  Here comes Railbus to you.
8
10
 
@@ -18,18 +20,16 @@ And then execute:
18
20
 
19
21
  $ bundle install
20
22
 
21
- Or install it yourself as:
22
-
23
- $ gem install railbus
24
-
25
23
  You may call this to generate example file and install JavaScript dependencies:
26
24
 
27
25
  $ rails g railbus:install
28
26
 
29
27
  Or do it manually:
30
28
 
31
- 1. Run `yarn add @crosspath/yambus`.
32
- 2. Create `*.js.erb` file in `app/javascript` (e.g. `lib/routes.js.erb`)
29
+ 1. Run `yarn add @crosspath/yambus`. See its [README][1] for usage info.
30
+ 2. Recommended step: add adapter for [Axios][2] or [`fetch` function][3].
31
+ Default: add adapter for Axios as `yarn add @crosspath/yambus-axios`.
32
+ 3. Create `*.js.erb` file in `app/javascript` (e.g. `lib/routes.js.erb`)
33
33
  to use it with Webpack:
34
34
 
35
35
  ```erb
@@ -37,17 +37,23 @@ Or do it manually:
37
37
  <%= Railbus.generate %>
38
38
  ```
39
39
 
40
- And the last step, require this file in your `.js` files where you want to use application routes.
40
+ And the last step, require this file in your `.js` files where you want to use
41
+ application routes.
41
42
 
42
43
  ```js
43
44
  import Routes from 'lib/routes'
44
45
  ```
45
46
 
47
+ [1]: https://github.com/crosspath/yambus
48
+ [2]: https://github.com/crosspath/yambus/blob/master/adapters/axios/README.md
49
+ [3]: https://github.com/crosspath/yambus/blob/master/adapters/fetch/README.md
50
+
46
51
  ## Usage
47
52
 
48
53
  In short:
49
54
 
50
- 1. See output of `rails routes`, it includes route names. You may use these names in JS as functions for XHR requests.
55
+ 1. See output of `rails routes`, it includes route names. You may use these
56
+ names in JS as functions for requests.
51
57
  2. Append `_path` to a route name to get its URL.
52
58
 
53
59
  Route names in JS depend on route names in Rails:
@@ -62,48 +68,22 @@ create | POST | create_{singular_name} | create_{singular_name}_path
62
68
  update | PUT/PATCH | update_{singular_name} | update_{singular_name}_path
63
69
  destroy | DELETE | delete_{singular_name} | delete_{singular_name}_path
64
70
 
65
- ### Functions' arguments
66
-
67
- Here `String or Number, ...` represents values used in paths, e.g.
68
- `:id`, `:category_id` (zero, one or more params).
69
-
70
- And `...path_params` means hash-like object with values for paths, e.g.
71
- `{id: 123, category_id: 56}` (zero, one or more params).
72
-
73
- `data` means request body (payload), it can be hash-like object, `FormData` and so on, its allowed types depend on XHR library or request function.
74
-
75
- All arguments are optional.
76
-
77
- ```js
78
- // Request `index`, `show`, `new`, `edit`, `destroy` actions.
79
- ({format: String, ...path_params, ...url_options})
80
- // Or:
81
- (String or Number, ..., {format: String, ...url_options})
82
-
83
- // Request `create` and `update` actions.
84
- ({format: String, ...path_params, ...url_options}, data)
85
- // Or:
86
- (String or Number, ..., {format: String, ...url_options}, data)
87
-
88
- // Get path for any action (does not include query string starting with '?').
89
- ({format: String, ...path_params})
90
- // Or:
91
- (String or Number, ..., {format: String})
92
- ```
93
-
94
71
  ### Configuration
95
72
 
96
73
  By default Railbus generates functions for all routes defined
97
- in `Rails.application` and these functions use `axios`. You may change it:
74
+ in `Rails.application`, and these functions use library `axios`.
98
75
 
99
- ```js
76
+ You may change it:
77
+
78
+ ```erb
100
79
  <%=
101
80
  Railbus.generate(
102
81
  # Here `YourApp::Engine` inherits `Rails::Engine`.
103
82
  # Default: `Rails.application`.
104
83
  app: YourApp::Engine,
105
84
 
106
- # 'axios' or the name of function defined or imported in this file.
85
+ # 'axios', 'fetch' or the name of function defined or imported in this file.
86
+ # Appropriate NPM package for adapter should be installed.
107
87
  # Default: 'axios'.
108
88
  client: 'request_api',
109
89
 
@@ -113,22 +93,41 @@ in `Rails.application` and these functions use `axios`. You may change it:
113
93
 
114
94
  # Exclude all route paths matching regexpes.
115
95
  # Empty array: do not exclude any routes (default).
116
- exclude: [/edit|new/]
96
+ exclude: [/edit|new/],
97
+
98
+ # 'null' or the name of function defined or imported in this file.
99
+ #
100
+ # This function will be called before doing requests. It accepts
101
+ # `url`, `options`, `route`, `params` and should return `options`.
102
+ #
103
+ # You may use it to add options before performing request or for logging
104
+ # requests.
105
+ #
106
+ # Default: 'null' (no function).
107
+ set_options: 'null'
117
108
  )
118
109
  %>
110
+ ```
111
+ ```js
112
+ import axios from 'axios'
119
113
 
120
- import axios from 'axios';
114
+ // For example, pass all requests to subdomain `api`.
121
115
  const axios_api = axios.create({
122
- baseURL: `${document.location.origin}/api/`
116
+ baseURL: `${document.location.protocol}//api.${document.location.host}/`
123
117
  })
124
118
 
125
- function request_api(route, params) {
126
- return axios_api.request({
119
+ function request_api(route, params, set_options) {
120
+ let options = {
127
121
  url: params.path,
128
122
  method: route.verb,
129
123
  params: params.url_options,
130
124
  data: params.data
131
- })
125
+ }
126
+
127
+ if (typeof set_options === 'function')
128
+ options = set_options(params.path, options, route, params)
129
+
130
+ return axios_api.request(options)
132
131
  }
133
132
  ```
134
133
 
@@ -146,8 +145,9 @@ namespace :my do
146
145
  end
147
146
  ```
148
147
 
149
- To make XHR requests with promises you may do this in JS
150
- ([axios](https://github.com/axios/axios) required):
148
+ Assume you have generated object with routes in JS file `lib/routes`.
149
+
150
+ You may do this in JS to call requests:
151
151
 
152
152
  ```js
153
153
  import Routes from 'lib/routes'
@@ -155,48 +155,55 @@ import Routes from 'lib/routes'
155
155
  // Request all favourites and print to console. Note: using namespace `my`.
156
156
  // It will call `My::FavouritesController#index`.
157
157
  // Path: '/my/favourites'.
158
- Routes.my_favourites().then(response => console.log(response.data))
158
+ Routes.my_favourites().then(resp => console.log(resp.data))
159
159
 
160
160
  // Request all news and print to console.
161
161
  // String `index` appended to distinguish `index` and `show` actions.
162
162
  // It will call `NewsController#index`.
163
163
  // Path: '/news'.
164
- Routes.news_index().then(response => console.log(response.data))
164
+ Routes.news_index().then(resp => console.log(resp.data))
165
165
 
166
166
  // Request all news filtered by date, and print to console.
167
167
  // `NewsController#index` with param `date` in query string (GET).
168
168
  // Path: '/news' with query string '?date=2020-12-31'.
169
- Routes.news_index({date: '2020-12-31'}).then(response => console.log(response.data))
169
+ Routes.news_index({date: '2020-12-31'}).then(resp => console.log(resp.data))
170
170
 
171
171
  // Request one news and print to console.
172
172
  // `NewsController#show` with param `id` = 327 (GET).
173
173
  // Path: '/news/327'.
174
- Routes.news(327).then(response => console.log(response.data))
174
+ Routes.news(327).then(resp => console.log(resp.data))
175
175
  // Or
176
- Routes.news({id: 327}).then(response => console.log(response.data))
176
+ Routes.news({id: 327}).then(resp => console.log(resp.data))
177
177
 
178
178
  // Specify format (for example, '.json').
179
179
  // `NewsController#show` with param `id` = 327 (GET) and `format` = 'json'.
180
180
  // Path: '/news/327.json'.
181
- Routes.news(327, {format: 'json'}).then(response => console.log(response.data))
181
+ Routes.news(327, {format: 'json'}).then(resp => console.log(resp.data))
182
182
  // Or
183
- Routes.news({id: 327, format: 'json'}).then(response => console.log(response.data))
183
+ Routes.news({id: 327, format: 'json'}).then(resp => console.log(resp.data))
184
184
 
185
185
  // Create news with given title.
186
186
  // `NewsController#create` with param `title` (POST).
187
- Routes.create_news({title: 'Bears showed up in Tomsk'}).then(response => console.log(response.data))
187
+ Routes.create_news({title: 'Bears showed up in Tomsk'}).then(resp => {
188
+ console.log(resp.data)
189
+ })
188
190
 
189
191
  // Create message with given title. Note: `message`, singular form.
190
192
  // `MessagesController#create` with params `body`, `to` (POST).
191
- Routes.create_message({body: 'Fantastic!', to: 23}).then(response => console.log(response.data))
193
+ Routes.create_message({body: 'Fantastic!', to: 23}).then(resp => {
194
+ console.log(resp.data)
195
+ })
192
196
 
193
197
  // Create message with given title. Note: using namespace `my`.
194
198
  // `My::FavouritesController#create` with param `url` (POST).
195
- Routes.create_my_favourite({url: 'https://best.site'}).then(response => console.log(response.data))
199
+ Routes.create_my_favourite({url: 'https://best.site'}).then(resp => {
200
+ console.log(resp.data)
201
+ })
196
202
 
197
203
  // Attach an image to the news.
198
- // `ImageController#create` with param `news_id` = 41 (GET), `blob` (POST).
199
- Routes.create_news_image(41, {blob: file})
204
+ // `ImageController#create` with params `news_id` = 41 (GET),
205
+ // `my_attachment` (POST).
206
+ Routes.create_news_image(41, {my_attachment: file})
200
207
 
201
208
  // Get URL for `create` action.
202
209
  Routes.create_my_favourite_path() // => 'my/favourites'
@@ -204,26 +211,29 @@ Routes.create_my_favourite_path() // => 'my/favourites'
204
211
 
205
212
  ## Development
206
213
 
207
- 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.
214
+ After checking out the repo, run `bin/setup` to install dependencies.
215
+ Then, run `rake spec` to run the tests. You can also run `bin/console` for
216
+ an interactive prompt that will allow you to experiment.
208
217
 
209
218
  To install this gem onto your local machine, run `bundle exec rake install`.
210
219
 
211
220
  TODO:
212
221
 
213
- - Support [fetch](https://developer.mozilla.org/ru/docs/Web/API/Fetch_API/Using_Fetch)
214
- - Tests
222
+ :white_check_mark: Support fetch — done!\
223
+ :black_square_button: Tests
215
224
 
216
225
  ## Contributing
217
226
 
218
- Bug reports and pull requests are welcome on GitHub at [github.com/crosspath/railbus](https://github.com/crosspath/railbus).
227
+ Bug reports and pull requests are welcome on GitHub at
228
+ [github.com/crosspath/railbus](https://github.com/crosspath/railbus).
219
229
 
220
230
  Please do not change version number in pull requests.
221
231
 
222
232
  ## Alternative solutions
223
233
 
224
234
  1. [rswag](https://github.com/rswag/rswag) +
225
- [swagger-js](https://github.com/swagger-api/swagger-js) +
226
- your integration specs (tests)
235
+ [swagger-js](https://github.com/swagger-api/swagger-js) +
236
+ your integration specs (tests)
227
237
  2. [railsware/js-routes](https://github.com/railsware/js-routes)
228
238
  3. [mtrpcic/js-routes](https://github.com/mtrpcic/js-routes)
229
239
  4. [less-js-routes](https://github.com/stevenbristol/less-js-routes)
@@ -231,4 +241,5 @@ Please do not change version number in pull requests.
231
241
 
232
242
  ## License
233
243
 
234
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
244
+ The gem is available as open source under the terms of
245
+ the [MIT License](https://opensource.org/licenses/MIT).
@@ -6,7 +6,7 @@ module Railbus
6
6
  desc 'Install dependencies and example file with routes'
7
7
 
8
8
  def install
9
- exit unless run 'yarn add @crosspath/yambus axios'
9
+ exit unless run 'yarn add @crosspath/yambus @crosspath/yambus-axios'
10
10
 
11
11
  create_file('app/javascript/lib/routes.js.erb') do |f|
12
12
  <<-LINE
@@ -9,11 +9,14 @@ require_relative 'railbus/route_set_presenter'
9
9
  module Railbus
10
10
  module_function
11
11
 
12
+ CLIENTS = %w[axios fetch]
13
+
12
14
  def generate(
13
- app: Rails.application,
14
- client: 'axios',
15
- include: [],
16
- exclude: []
15
+ app: Rails.application,
16
+ client: 'axios',
17
+ include: [],
18
+ exclude: [],
19
+ set_options: 'null'
17
20
  )
18
21
  route_set = RouteSet.new(app, include, exclude)
19
22
  routes_json = Railbus::RouteSetPresenter.to_h(route_set).to_json
@@ -21,7 +24,7 @@ module Railbus
21
24
  js_template = File.join(__dir__, 'railbus', 'templates', 'js.erb')
22
25
  erb_engine = Erubi::Engine.new(File.read(js_template))
23
26
 
24
- # Template uses `routes_json`, `client`
27
+ # Template uses `routes_json`, `client`, 'set_options'
25
28
  client = client.to_s
26
29
  eval(erb_engine.src)
27
30
  end
@@ -23,9 +23,14 @@ class Railbus::RouteSet
23
23
  private
24
24
 
25
25
  def paths_for_app(app, include, exclude)
26
+ mounted_at = app.routes.find_script_name({})
27
+
26
28
  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
+ formatter = route.instance_variable_get(:@path_formatter)
30
+ raw_parts = formatter.instance_variable_get(:@parts)
31
+ raw_parts.unshift(mounted_at)
32
+
33
+ route_parts = parts_combined(raw_parts)
29
34
 
30
35
  path = join_parts(route_parts)
31
36
  next nil unless include_path?(path, include, exclude)
@@ -1,7 +1,6 @@
1
1
  import yambus from '@crosspath/yambus'
2
-
3
- <% if client == 'axios' %>
4
- import axios from 'axios'
2
+ <% if Railbus::CLIENTS.include?(client) %>
3
+ import { request } from '@crosspath/yambus-<%= client %>'
5
4
  <% end %>
6
5
 
7
6
  const routes = <%= routes_json.html_safe %>
@@ -10,15 +9,10 @@ const route_functions = yambus.generate_route_functions(
10
9
  routes,
11
10
  (route, args) => {
12
11
  const params = yambus.build_request_options(route, args)
13
- <% if client == 'axios' %>
14
- return axios.request({
15
- url: params.path,
16
- method: route.verb,
17
- params: params.url_options,
18
- data: params.data
19
- })
12
+ <% if Railbus::CLIENTS.include?(client) %>
13
+ return request(route, params, <%= set_options %>)
20
14
  <% else %>
21
- return <%= client %>(route, params)
15
+ return <%= client %>(route, params, <%= set_options %>)
22
16
  <% end %>
23
17
  }
24
18
  )
@@ -1,3 +1,3 @@
1
1
  module Railbus
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: railbus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evgeniy Nochevnov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-31 00:00:00.000000000 Z
11
+ date: 2020-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport