js-routes 2.1.2 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/Readme.md +54 -52
- data/lib/js_routes/generators/middleware.rb +33 -0
- data/lib/js_routes/generators/webpacker.rb +1 -1
- data/lib/js_routes/middleware.rb +36 -0
- data/lib/js_routes/version.rb +1 -1
- data/lib/js_routes.rb +10 -5
- data/lib/routes.js +6 -4
- data/lib/routes.ts +7 -5
- data/spec/js_routes/module_types/amd_spec.rb +6 -5
- data/spec/js_routes/module_types/nil_spec.rb +86 -0
- data/spec/js_routes/module_types/umd_spec.rb +1 -1
- data/spec/js_routes/options_spec.rb +33 -51
- data/spec/spec_helper.rb +1 -2
- data/spec/support/routes.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 315ddd617bc6630cf5858afc5ba38d2c204f6167a7984ccdaf7171a50404e418
|
4
|
+
data.tar.gz: 676d2d36107ee524c07517143499173c0658731cc06d1c52753e3ab2f4e6cb81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c7f715e9afd02d1daebb882381e328595beca59a6a6d8c10a3a1518801522090e986c6b362174aaa9c51faf91508ee8e1cc6fff8ba118a08c32eb26c7205ba1
|
7
|
+
data.tar.gz: 7f70bfa95a1fb42092f20118bb3f22f07e459ccc6f95b8d3b0651faf0457266152465873da6a4dfddc4d52df006d6f5b991e3608a083c1eb524fef5ed77ff0c8
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
## master
|
2
2
|
|
3
|
+
## v2.2.0
|
4
|
+
|
5
|
+
* Use Rack Middleware to automatically update routes file in development [#288](https://github.com/railsware/js-routes/issues/288)
|
6
|
+
* This setup is now a default recommended due to lack of any downside comparing to [ERB Loader](./Readme.md#webpacker) and [Manual Setup](./Readme.md#advanced-setup)
|
7
|
+
|
8
|
+
## v2.1.3
|
9
|
+
|
10
|
+
* Fix `default_url_options` bug. [#290](https://github.com/railsware/js-routes/issues/290)
|
11
|
+
|
3
12
|
## v2.1.2
|
4
13
|
|
5
14
|
* Improve browser window object detection. [#287](https://github.com/railsware/js-routes/issues/287)
|
data/Readme.md
CHANGED
@@ -19,10 +19,13 @@ gem "js-routes"
|
|
19
19
|
There are 3 possible ways to setup JsRoutes:
|
20
20
|
|
21
21
|
* [Quick and easy](#quick-start)
|
22
|
-
*
|
22
|
+
* Uses Rack Middleware to automatically update routes locally
|
23
|
+
* Works great for a simple Rails application
|
23
24
|
* [Webpacker](#webpacker) automatic updates
|
24
25
|
* Requires ESM module system (the default)
|
25
26
|
* Doesn't support typescript definitions
|
27
|
+
* [Advanced Setup](#advanced-setup)
|
28
|
+
* Allows very custom setups
|
26
29
|
* [Sprockets](#sprockets) legacy
|
27
30
|
* Deprecated and not recommended for modern apps
|
28
31
|
|
@@ -30,36 +33,20 @@ There are 3 possible ways to setup JsRoutes:
|
|
30
33
|
|
31
34
|
### Quick Start
|
32
35
|
|
36
|
+
Setup [Rack Middleware](https://guides.rubyonrails.org/rails_on_rack.html#action-dispatcher-middleware-stack) to automatically generate and maintain `routes.js` file and corresponding [Typescript definitions](https://www.typescriptlang.org/docs/handbook/declaration-files/templates/module-d-ts.html) `routes.d.ts`:
|
37
|
+
|
33
38
|
Run:
|
34
39
|
|
35
40
|
``` sh
|
36
|
-
|
37
|
-
# OR for typescript support
|
38
|
-
rake js:routes:typescript
|
41
|
+
rails generate js_routes:middleware
|
39
42
|
```
|
40
43
|
|
41
|
-
**IMPORTANT**: that this setup requires the rake task to be run each time routes file is updated.
|
42
|
-
|
43
|
-
Individual routes can be imported using:
|
44
|
-
|
45
|
-
``` javascript
|
46
|
-
import {edit_post_path, posts_path} from 'routes';
|
47
|
-
console.log(posts_path({format: 'json'})) // => "/posts.json"
|
48
|
-
console.log(edit_post_path(1)) // => "/posts/1/edit"
|
49
|
-
```
|
50
|
-
|
51
|
-
Make routes available globally in `app/javascript/packs/application.js`:
|
52
|
-
|
53
|
-
``` javascript
|
54
|
-
import * as Routes from 'routes';
|
55
|
-
window.Routes = Routes;
|
56
|
-
```
|
57
44
|
|
58
45
|
<div id='webpacker'></div>
|
59
46
|
|
60
47
|
### Webpacker + automatic updates - Typescript
|
61
48
|
|
62
|
-
**IMPORTANT**: this setup doesn't support IDE autocompletion with [Typescript](
|
49
|
+
**IMPORTANT**: this setup doesn't support IDE autocompletion with [Typescript](https://www.typescriptlang.org/docs/handbook/declaration-files/templates/module-d-ts.html)
|
63
50
|
|
64
51
|
|
65
52
|
#### Use a Generator
|
@@ -118,9 +105,52 @@ import * as Routes from 'routes.js.erb';
|
|
118
105
|
window.Routes = Routes;
|
119
106
|
```
|
120
107
|
|
108
|
+
<div id='advanced-setup'></div>
|
109
|
+
|
110
|
+
### Advanced Setup
|
111
|
+
|
112
|
+
**IMPORTANT**: that this setup requires the JS routes file to be updates manually
|
113
|
+
|
114
|
+
You can run every time you want to generate a routes file:
|
115
|
+
|
116
|
+
``` sh
|
117
|
+
rake js:routes
|
118
|
+
# OR for typescript support
|
119
|
+
rake js:routes:typescript
|
120
|
+
```
|
121
|
+
|
122
|
+
In case you need multiple route files for different parts of your application, you have to create the files manually.
|
123
|
+
If your application has an `admin` and an `application` namespace for example:
|
124
|
+
|
125
|
+
``` erb
|
126
|
+
// app/javascript/admin/routes.js.erb
|
127
|
+
<%= JsRoutes.generate(include: /admin/) %>
|
128
|
+
```
|
129
|
+
|
130
|
+
``` erb
|
131
|
+
// app/javascript/customer/routes.js.erb
|
132
|
+
<%= JsRoutes.generate(exclude: /admin/) %>
|
133
|
+
```
|
134
|
+
|
135
|
+
You can manipulate the generated helper manually by injecting ruby into javascript:
|
136
|
+
|
137
|
+
``` erb
|
138
|
+
export const routes = <%= JsRoutes.generate(module_type: nil, namespace: nil) %>
|
139
|
+
```
|
140
|
+
|
141
|
+
If you want to generate the routes files outside of the asset pipeline, you can use `JsRoutes.generate!`:
|
142
|
+
|
143
|
+
``` ruby
|
144
|
+
path = Rails.root.join("app/javascript")
|
145
|
+
|
146
|
+
JsRoutes.generate!("#{path}/app_routes.js", exclude: [/^admin_/, /^api_/])
|
147
|
+
JsRoutes.generate!("#{path}/adm_routes.js", include: /^admin_/)
|
148
|
+
JsRoutes.generate!("#{path}/api_routes.js", include: /^api_/, default_url_options: {format: "json"})
|
149
|
+
```
|
150
|
+
|
121
151
|
<div id='definitions'></div>
|
122
152
|
|
123
|
-
|
153
|
+
#### Typescript Definitions
|
124
154
|
|
125
155
|
JsRoutes has typescript support out of the box.
|
126
156
|
|
@@ -230,6 +260,8 @@ Options to configure JavaScript file generator. These options are only available
|
|
230
260
|
* `file` - a file location where generated routes are stored
|
231
261
|
* Default: `app/javascript/routes.js` if setup with Webpacker, otherwise `app/assets/javascripts/routes.js` if setup with Sprockets.
|
232
262
|
|
263
|
+
<div id="formatter-options"></div>
|
264
|
+
|
233
265
|
#### Formatter Options
|
234
266
|
|
235
267
|
Options to configure routes formatting. These options are available both in Ruby and JavaScript context.
|
@@ -248,36 +280,6 @@ Options to configure routes formatting. These options are available both in Ruby
|
|
248
280
|
* This option exists because JS doesn't provide a difference between an object and a hash
|
249
281
|
* Default: `_options`
|
250
282
|
|
251
|
-
## Advanced Setup
|
252
|
-
|
253
|
-
In case you need multiple route files for different parts of your application, you have to create the files manually.
|
254
|
-
If your application has an `admin` and an `application` namespace for example:
|
255
|
-
|
256
|
-
``` erb
|
257
|
-
// app/javascript/admin/routes.js.erb
|
258
|
-
<%= JsRoutes.generate(include: /admin/) %>
|
259
|
-
```
|
260
|
-
|
261
|
-
``` erb
|
262
|
-
// app/javascript/customer/routes.js.erb
|
263
|
-
<%= JsRoutes.generate(exclude: /admin/) %>
|
264
|
-
```
|
265
|
-
|
266
|
-
You can manipulate the generated helper manually by injecting ruby into javascript:
|
267
|
-
|
268
|
-
``` erb
|
269
|
-
export const routes = <%= JsRoutes.generate(module_type: nil, namespace: nil) %>
|
270
|
-
```
|
271
|
-
|
272
|
-
If you want to generate the routes files outside of the asset pipeline, you can use `JsRoutes.generate!`:
|
273
|
-
|
274
|
-
``` ruby
|
275
|
-
path = Rails.root.join("app/javascript")
|
276
|
-
|
277
|
-
JsRoutes.generate!("#{path}/app_routes.js", exclude: [/^admin_/, /^api_/])
|
278
|
-
JsRoutes.generate!("#{path}/adm_routes.js", include: /^admin_/)
|
279
|
-
JsRoutes.generate!("#{path}/api_routes.js", include: /^api_/, default_url_options: {format: "json"})
|
280
|
-
```
|
281
283
|
|
282
284
|
## Usage
|
283
285
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "rails/generators"
|
2
|
+
|
3
|
+
class JsRoutes::Generators::Middleware < Rails::Generators::Base
|
4
|
+
|
5
|
+
source_root File.expand_path(__FILE__ + "/../../../templates")
|
6
|
+
|
7
|
+
def create_middleware
|
8
|
+
copy_file "initializer.rb", "config/initializers/js_routes.rb"
|
9
|
+
# copy_file "erb.js", "config/webpack/loaders/erb.js"
|
10
|
+
# copy_file "routes.js.erb", "app/javascript/routes.js.erb"
|
11
|
+
# inject_into_file "config/webpack/environment.js", loader_content
|
12
|
+
inject_into_file "app/javascript/packs/application.js", pack_content
|
13
|
+
inject_into_file "config/environments/development.rb", middleware_content, before: /^end\n\z/
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
def pack_content
|
19
|
+
<<-JS
|
20
|
+
import * as Routes from '../routes';
|
21
|
+
window.Routes = Routes;
|
22
|
+
JS
|
23
|
+
end
|
24
|
+
|
25
|
+
def middleware_content
|
26
|
+
<<-RB
|
27
|
+
|
28
|
+
# Automatically update routes.js file
|
29
|
+
# when routes.rb is changed
|
30
|
+
config.middleware.use(JsRoutes::Middleware)
|
31
|
+
RB
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class JsRoutes
|
2
|
+
# A Rack middleware that automatically updates routes file
|
3
|
+
# whenever routes.rb is modified
|
4
|
+
#
|
5
|
+
# Inspired by
|
6
|
+
# https://github.com/fnando/i18n-js/blob/main/lib/i18n/js/middleware.rb
|
7
|
+
class Middleware
|
8
|
+
def initialize(app)
|
9
|
+
@app = app
|
10
|
+
@routes_file = Rails.root.join("config/routes.rb")
|
11
|
+
@mtime = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
update_js_routes
|
16
|
+
@app.call(env)
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def update_js_routes
|
22
|
+
new_mtime = routes_mtime
|
23
|
+
unless new_mtime == @mtime
|
24
|
+
JsRoutes.generate!
|
25
|
+
JsRoutes.definitions!
|
26
|
+
@mtime = new_mtime
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def routes_mtime
|
31
|
+
File.mtime(@routes_file)
|
32
|
+
rescue Errno::ENOENT
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/js_routes/version.rb
CHANGED
data/lib/js_routes.rb
CHANGED
@@ -132,7 +132,7 @@ class JsRoutes
|
|
132
132
|
end
|
133
133
|
|
134
134
|
def definitions!(file_name = nil, **opts)
|
135
|
-
file_name ||= configuration.file&.sub
|
135
|
+
file_name ||= configuration.file&.sub(%r{(\.d)?\.(j|t)s\Z}, ".d.ts")
|
136
136
|
generate!(file_name, module_type: 'DTS', **opts)
|
137
137
|
end
|
138
138
|
|
@@ -151,7 +151,7 @@ class JsRoutes
|
|
151
151
|
|
152
152
|
def generate
|
153
153
|
# Ensure routes are loaded. If they're not, load them.
|
154
|
-
if named_routes.
|
154
|
+
if named_routes.empty? && application.respond_to?(:reload_routes!)
|
155
155
|
application.reload_routes!
|
156
156
|
end
|
157
157
|
content = File.read(@configuration.source_file)
|
@@ -273,12 +273,13 @@ export {};
|
|
273
273
|
end
|
274
274
|
|
275
275
|
def app_from_route(route)
|
276
|
+
app = route.app
|
276
277
|
# rails engine in Rails 4.2 use additional
|
277
278
|
# ActionDispatch::Routing::Mapper::Constraints, which contain app
|
278
|
-
if
|
279
|
-
|
279
|
+
if app.respond_to?(:app) && app.respond_to?(:constraints)
|
280
|
+
app.app
|
280
281
|
else
|
281
|
-
|
282
|
+
app
|
282
283
|
end
|
283
284
|
end
|
284
285
|
|
@@ -456,6 +457,10 @@ JS
|
|
456
457
|
].compact
|
457
458
|
end
|
458
459
|
end
|
460
|
+
module Generators
|
461
|
+
end
|
459
462
|
end
|
460
463
|
|
464
|
+
require "js_routes/middleware"
|
461
465
|
require "js_routes/generators/webpacker"
|
466
|
+
require "js_routes/generators/middleware"
|
data/lib/routes.js
CHANGED
@@ -74,7 +74,7 @@ RubyVariables.WRAPPER((that) => {
|
|
74
74
|
Utils.namespace(Root, RubyVariables.NAMESPACE, routes);
|
75
75
|
},
|
76
76
|
isSupported() {
|
77
|
-
return !!Root;
|
77
|
+
return !RubyVariables.NAMESPACE || !!Root;
|
78
78
|
},
|
79
79
|
},
|
80
80
|
DTS: {
|
@@ -205,7 +205,9 @@ RubyVariables.WRAPPER((that) => {
|
|
205
205
|
throw new Error("Too many parameters provided for path");
|
206
206
|
}
|
207
207
|
let use_all_parts = args.length > required_params.length;
|
208
|
-
const parts_options = {
|
208
|
+
const parts_options = {
|
209
|
+
...this.configuration.default_url_options,
|
210
|
+
};
|
209
211
|
for (const key in options) {
|
210
212
|
const value = options[key];
|
211
213
|
if (!hasProp(options, key))
|
@@ -446,7 +448,7 @@ RubyVariables.WRAPPER((that) => {
|
|
446
448
|
namespace(object, namespace, routes) {
|
447
449
|
const parts = (namespace === null || namespace === void 0 ? void 0 : namespace.split(".")) || [];
|
448
450
|
if (parts.length === 0) {
|
449
|
-
return
|
451
|
+
return;
|
450
452
|
}
|
451
453
|
for (let index = 0; index < parts.length; index++) {
|
452
454
|
const part = parts[index];
|
@@ -454,7 +456,7 @@ RubyVariables.WRAPPER((that) => {
|
|
454
456
|
object = object[part] || (object[part] = {});
|
455
457
|
}
|
456
458
|
else {
|
457
|
-
|
459
|
+
object[part] = routes;
|
458
460
|
}
|
459
461
|
}
|
460
462
|
}
|
data/lib/routes.ts
CHANGED
@@ -190,7 +190,7 @@ RubyVariables.WRAPPER(
|
|
190
190
|
Utils.namespace(Root, RubyVariables.NAMESPACE, routes);
|
191
191
|
},
|
192
192
|
isSupported() {
|
193
|
-
return !!Root;
|
193
|
+
return !RubyVariables.NAMESPACE || !!Root;
|
194
194
|
},
|
195
195
|
},
|
196
196
|
DTS: {
|
@@ -349,7 +349,9 @@ RubyVariables.WRAPPER(
|
|
349
349
|
throw new Error("Too many parameters provided for path");
|
350
350
|
}
|
351
351
|
let use_all_parts = args.length > required_params.length;
|
352
|
-
const parts_options: RouteParameters = {
|
352
|
+
const parts_options: RouteParameters = {
|
353
|
+
...this.configuration.default_url_options,
|
354
|
+
};
|
353
355
|
for (const key in options) {
|
354
356
|
const value = options[key];
|
355
357
|
if (!hasProp(options, key)) continue;
|
@@ -662,17 +664,17 @@ RubyVariables.WRAPPER(
|
|
662
664
|
object: any,
|
663
665
|
namespace: string | null | undefined,
|
664
666
|
routes: unknown
|
665
|
-
):
|
667
|
+
): void {
|
666
668
|
const parts = namespace?.split(".") || [];
|
667
669
|
if (parts.length === 0) {
|
668
|
-
return
|
670
|
+
return;
|
669
671
|
}
|
670
672
|
for (let index = 0; index < parts.length; index++) {
|
671
673
|
const part = parts[index];
|
672
674
|
if (index < parts.length - 1) {
|
673
675
|
object = object[part] || (object[part] = {});
|
674
676
|
} else {
|
675
|
-
|
677
|
+
object[part] = routes;
|
676
678
|
}
|
677
679
|
}
|
678
680
|
}
|
@@ -3,11 +3,12 @@ require "spec_helper"
|
|
3
3
|
describe JsRoutes, "compatibility with AMD/require.js" do
|
4
4
|
|
5
5
|
before(:each) do
|
6
|
-
evaljs("
|
7
|
-
evaljs("
|
8
|
-
evaljs("
|
6
|
+
evaljs("var global = this;", {force: true})
|
7
|
+
evaljs("global.GlobalCheck = {};")
|
8
|
+
evaljs("global.define = function (requirs, callback) { global.GlobalCheck['js-routes'] = callback.call(this); return global.GlobalCheck['js-routes']; };")
|
9
|
+
evaljs("global.define.amd = { jQuery: true };")
|
9
10
|
strRequire =<<EOF
|
10
|
-
|
11
|
+
global.require = function (r, callback) {
|
11
12
|
var allArgs, i;
|
12
13
|
|
13
14
|
allArgs = (function() {
|
@@ -15,7 +16,7 @@ describe JsRoutes, "compatibility with AMD/require.js" do
|
|
15
16
|
_results = [];
|
16
17
|
for (_i = 0, _len = r.length; _i < _len; _i++) {
|
17
18
|
i = r[_i];
|
18
|
-
_results.push(
|
19
|
+
_results.push(global.GlobalCheck[i]);
|
19
20
|
}
|
20
21
|
return _results;
|
21
22
|
})();
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe JsRoutes, "compatibility with NIL (legacy browser)" do
|
4
|
+
let(:generated_js) do
|
5
|
+
JsRoutes.generate(
|
6
|
+
module_type: nil,
|
7
|
+
include: /book|inboxes|inbox_message/,
|
8
|
+
**_options
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:_options) { {} }
|
13
|
+
describe "generated js" do
|
14
|
+
subject do
|
15
|
+
generated_js
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should call route function for each route" do
|
19
|
+
is_expected.to include("inboxes_path: __jsr.r(")
|
20
|
+
end
|
21
|
+
it "should have correct function without arguments signature" do
|
22
|
+
is_expected.to include('inboxes_path: __jsr.r({"format":{}}')
|
23
|
+
end
|
24
|
+
it "should have correct function with arguments signature" do
|
25
|
+
is_expected.to include('inbox_message_path: __jsr.r({"inbox_id":{"r":true},"id":{"r":true},"format":{}}')
|
26
|
+
end
|
27
|
+
it "should have correct function signature with unordered hash" do
|
28
|
+
is_expected.to include('inbox_message_attachment_path: __jsr.r({"inbox_id":{"r":true},"message_id":{"r":true},"id":{"r":true},"format":{}}')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "inline generation" do
|
33
|
+
let(:_options) { {namespace: nil} }
|
34
|
+
before do
|
35
|
+
evaljs("const r = #{generated_js}")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should be possible" do
|
39
|
+
expect(evaljs("r.inboxes_path()")).to eq(test_routes.inboxes_path())
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "namespace option" do
|
44
|
+
let(:_options) { {namespace: "PHM"} }
|
45
|
+
let(:_presetup) { "" }
|
46
|
+
before do
|
47
|
+
evaljs("var window = this;")
|
48
|
+
evaljs(_presetup)
|
49
|
+
evaljs(generated_js)
|
50
|
+
end
|
51
|
+
it "should use this namespace for routing" do
|
52
|
+
expect(evaljs("window.Routes")).to be_nil
|
53
|
+
expect(evaljs("window.PHM.inboxes_path")).not_to be_nil
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "is nested" do
|
57
|
+
context "and defined on client" do
|
58
|
+
let(:_presetup) { "window.PHM = {}" }
|
59
|
+
let(:_options) { {namespace: "PHM.Routes"} }
|
60
|
+
|
61
|
+
it "should use this namespace for routing" do
|
62
|
+
expect(evaljs("PHM.Routes.inboxes_path")).not_to be_nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "but undefined on client" do
|
67
|
+
let(:_options) { {namespace: "PHM.Routes"} }
|
68
|
+
|
69
|
+
it "should initialize namespace" do
|
70
|
+
expect(evaljs("window.PHM.Routes.inboxes_path")).not_to be_nil
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "and some parts are defined" do
|
75
|
+
let(:_presetup) { "window.PHM = { Utils: {} };" }
|
76
|
+
let(:_options) { {namespace: "PHM.Routes"} }
|
77
|
+
|
78
|
+
it "should not overwrite existing parts" do
|
79
|
+
expect(evaljs("window.PHM.Utils")).not_to be_nil
|
80
|
+
expect(evaljs("window.PHM.Routes.inboxes_path")).not_to be_nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
@@ -188,55 +188,19 @@ describe JsRoutes, "options" do
|
|
188
188
|
expect(evaljs("Routes.no_format_path({format: 'json'})")).to eq(test_routes.no_format_path(format: 'json'))
|
189
189
|
end
|
190
190
|
|
191
|
-
describe "namespace option" do
|
192
|
-
let(:_options) { {:namespace => "PHM"} }
|
193
|
-
it "should use this namespace for routing" do
|
194
|
-
expect(evaljs("window.Routes")).to be_nil
|
195
|
-
expect(evaljs("PHM.inbox_path")).not_to be_nil
|
196
|
-
end
|
197
|
-
|
198
|
-
context "is nil" do
|
199
|
-
let(:_options) { {:namespace => nil, include: /^inbox$/} }
|
200
|
-
it "should use this namespace for routing" do
|
201
|
-
evaljs("window.zz = #{generated_js}")
|
202
|
-
expect(evaljs("window.zz.inbox_path")).not_to be_nil
|
203
|
-
end
|
204
|
-
|
205
|
-
end
|
206
|
-
|
207
|
-
describe "is nested" do
|
208
|
-
context "and defined on client" do
|
209
|
-
let(:_presetup) { "window.PHM = {}" }
|
210
|
-
let(:_options) { {:namespace => "PHM.Routes"} }
|
211
|
-
it "should use this namespace for routing" do
|
212
|
-
expect(evaljs("PHM.Routes.inbox_path")).not_to be_nil
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
context "but undefined on client" do
|
217
|
-
let(:_options) { {:namespace => "PHM.Routes"} }
|
218
|
-
it "should initialize namespace" do
|
219
|
-
expect(evaljs("window.PHM.Routes.inbox_path")).not_to be_nil
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
context "and some parts are defined" do
|
224
|
-
let(:_presetup) { "window.PHM = { Utils: {} };" }
|
225
|
-
let(:_options) { {:namespace => "PHM.Routes"} }
|
226
|
-
it "should not overwrite existing parts" do
|
227
|
-
expect(evaljs("window.PHM.Utils")).not_to be_nil
|
228
|
-
expect(evaljs("window.PHM.Routes.inbox_path")).not_to be_nil
|
229
|
-
end
|
230
|
-
end
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
191
|
describe "default_url_options" do
|
235
192
|
context "with optional route parts" do
|
236
|
-
context "provided" do
|
193
|
+
context "provided by the default_url_options" do
|
237
194
|
let(:_options) { { :default_url_options => { :optional_id => "12", :format => "json" } } }
|
238
|
-
it "should use this
|
239
|
-
expect(evaljs("Routes.things_path()")).to eq(test_routes.things_path)
|
195
|
+
it "should use this options to fill optional parameters" do
|
196
|
+
expect(evaljs("Routes.things_path()")).to eq(test_routes.things_path(12))
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
context "provided inline by the method parameters" do
|
201
|
+
let(:options) { { :default_url_options => { :optional_id => "12" } } }
|
202
|
+
it "should overwrite the default_url_options" do
|
203
|
+
expect(evaljs("Routes.things_path({ optional_id: 34 })")).to eq(test_routes.things_path(optional_id: 34))
|
240
204
|
end
|
241
205
|
end
|
242
206
|
|
@@ -249,12 +213,25 @@ describe JsRoutes, "options" do
|
|
249
213
|
end
|
250
214
|
|
251
215
|
context "with required route parts" do
|
252
|
-
let(:_options) { {:default_url_options => {:inbox_id => "12"}} }
|
253
|
-
it "should use this
|
216
|
+
let(:_options) { { :default_url_options => { :inbox_id => "12" } } }
|
217
|
+
it "should use this options to fill optional parameters" do
|
254
218
|
expect(evaljs("Routes.inbox_messages_path()")).to eq(test_routes.inbox_messages_path)
|
255
219
|
end
|
256
220
|
end
|
257
221
|
|
222
|
+
context "with optional and required route parts" do
|
223
|
+
let(:_options) { {:default_url_options => { :optional_id => "12" } } }
|
224
|
+
it "should use this options to fill the optional parameters" do
|
225
|
+
expect(evaljs("Routes.thing_path(1)")).to eq test_routes.thing_path(1, { optional_id: "12" })
|
226
|
+
end
|
227
|
+
|
228
|
+
context "when passing options that do not have defaults" do
|
229
|
+
it "should use this options to fill the optional parameters" do
|
230
|
+
expect(evaljs("Routes.thing_path(1, { format: 'json' })")).to eq test_routes.thing_path(1, { optional_id: "12", format: "json" } ) # test_routes.thing_path needs optional_id here to generate the correct route. Not sure why.
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
258
235
|
context "when overwritten on JS level" do
|
259
236
|
let(:_options) { { :default_url_options => { :format => "json" } } }
|
260
237
|
it "uses JS defined value" do
|
@@ -421,8 +398,14 @@ describe JsRoutes, "options" do
|
|
421
398
|
host
|
422
399
|
end
|
423
400
|
|
424
|
-
|
425
|
-
|
401
|
+
let(:_presetup) do
|
402
|
+
window = {location: {
|
403
|
+
protocol: current_protocol,
|
404
|
+
hostname: current_hostname,
|
405
|
+
port: current_port,
|
406
|
+
host: current_host,
|
407
|
+
}}
|
408
|
+
"const window = #{ActiveSupport::JSON.encode(window)}"
|
426
409
|
end
|
427
410
|
|
428
411
|
context "without specifying a default host" do
|
@@ -434,7 +417,6 @@ describe JsRoutes, "options" do
|
|
434
417
|
expect(evaljs("Routes.inbox_url(1)")).to eq("http://current.example.com#{test_routes.inbox_path(1)}")
|
435
418
|
expect(evaljs("Routes.inbox_url(1, { test_key: \"test_val\" })")).to eq("http://current.example.com#{test_routes.inbox_path(1, :test_key => "test_val")}")
|
436
419
|
expect(evaljs("Routes.new_session_url()")).to eq("https://current.example.com#{test_routes.new_session_path}")
|
437
|
-
|
438
420
|
end
|
439
421
|
|
440
422
|
it "doesn't use current when specified in the route" do
|
data/spec/spec_helper.rb
CHANGED
@@ -108,11 +108,10 @@ RSpec.configure do |config|
|
|
108
108
|
end
|
109
109
|
|
110
110
|
config.before :each do
|
111
|
-
evaljs("var window = this;", {force: true})
|
112
|
-
|
113
111
|
log = proc do |*values|
|
114
112
|
puts values.map(&:inspect).join(", ")
|
115
113
|
end
|
114
|
+
|
116
115
|
if defined?(JRUBY_VERSION)
|
117
116
|
jscontext[:"console.log"] = lambda do |context, *values|
|
118
117
|
log(*values)
|
data/spec/support/routes.rb
CHANGED
@@ -62,7 +62,7 @@ def draw_routes
|
|
62
62
|
|
63
63
|
resources :portals, :port => 8080, only: [:index]
|
64
64
|
|
65
|
-
get '/with_defaults' => 'foo#foo', defaults: { bar: 'tested', format: :json }, format:
|
65
|
+
get '/with_defaults' => 'foo#foo', defaults: { bar: 'tested', format: :json }, format: true
|
66
66
|
|
67
67
|
namespace :api, format: true, defaults: {format: 'json'} do
|
68
68
|
get "/purchases" => "purchases#index"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: js-routes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bogdan Gusiev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -171,7 +171,9 @@ files:
|
|
171
171
|
- lib/js-routes.rb
|
172
172
|
- lib/js_routes.rb
|
173
173
|
- lib/js_routes/engine.rb
|
174
|
+
- lib/js_routes/generators/middleware.rb
|
174
175
|
- lib/js_routes/generators/webpacker.rb
|
176
|
+
- lib/js_routes/middleware.rb
|
175
177
|
- lib/js_routes/version.rb
|
176
178
|
- lib/routes.d.ts
|
177
179
|
- lib/routes.js
|
@@ -191,6 +193,7 @@ files:
|
|
191
193
|
- spec/js_routes/module_types/dts/test.spec.ts
|
192
194
|
- spec/js_routes/module_types/dts_spec.rb
|
193
195
|
- spec/js_routes/module_types/esm_spec.rb
|
196
|
+
- spec/js_routes/module_types/nil_spec.rb
|
194
197
|
- spec/js_routes/module_types/umd_spec.rb
|
195
198
|
- spec/js_routes/options_spec.rb
|
196
199
|
- spec/js_routes/rails_routes_compatibility_spec.rb
|