railbus 0.1.2 → 0.2.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 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