js-routes 1.4.6 → 1.4.12
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 +4 -4
- data/.gitignore +2 -0
- data/CHANGELOG.md +22 -0
- data/Readme.md +119 -57
- data/js-routes.gemspec +1 -1
- data/lib/js_routes.rb +52 -41
- data/lib/js_routes/engine.rb +0 -1
- data/lib/js_routes/version.rb +1 -1
- data/lib/routes.js +11 -15
- data/lib/routes.js.coffee +6 -12
- data/spec/dummy/app/assets/config/manifest.js +2 -0
- data/spec/js_routes/amd_compatibility_spec.rb +3 -0
- data/spec/js_routes/generated_javascript_spec.rb +0 -5
- data/spec/js_routes/options_spec.rb +28 -18
- data/spec/spec_helper.rb +2 -2
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 87926593b4aa4a92ce85269fafd11238dbba0e8354bd4f4cffd03c56a765f519
|
4
|
+
data.tar.gz: ad3ee96de22c9b10c89ad38e96eede4ef1fa040051e37cb75e4697a4ecd366e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a7309d0f38ab6a923d23571869da7206e0e1aa4541fff1354e15e8fffe3fe634001ee3959dc6033e30044010e63c7e9c910145fdea0f9c0a14f63b391314954
|
7
|
+
data.tar.gz: ca121924d248b98c5429c1b0a4e2052dd22d48b43eb97ca78b6d18caf29f79b2bb51b78a190c7cecbb2cdd20d2c772f3c137a0ddd11fe49cdd8f525ac9b087e0
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,27 @@
|
|
1
1
|
## master
|
2
2
|
|
3
|
+
## v1.4.12
|
4
|
+
|
5
|
+
* Improve compatibility with node environment #269.
|
6
|
+
* Change default file location configuration to Webpacker if both Webpacker and Sprockets are loaded
|
7
|
+
|
8
|
+
## v1.4.11
|
9
|
+
|
10
|
+
* Use app/javascript/routes.js as a default file location if app/javascript directory exists
|
11
|
+
* Add `default` export for better experience when used as es6 module
|
12
|
+
|
13
|
+
## v1.4.10
|
14
|
+
|
15
|
+
* Require engine only when sprockets is loaded #257.
|
16
|
+
|
17
|
+
## v1.4.9
|
18
|
+
|
19
|
+
* Allow to specify null namespace and receive routes as an object without assigning it anywhere #247
|
20
|
+
|
21
|
+
## v1.4.7
|
22
|
+
|
23
|
+
* Fix a LocalJumpError on secondary initialization of the app #248
|
24
|
+
|
3
25
|
## v1.4.6
|
4
26
|
|
5
27
|
* Fix regression of #244 in #243
|
data/Readme.md
CHANGED
@@ -12,9 +12,80 @@ Your Rails Gemfile:
|
|
12
12
|
gem "js-routes"
|
13
13
|
```
|
14
14
|
|
15
|
-
|
15
|
+
## Setup
|
16
16
|
|
17
|
-
|
17
|
+
Run:
|
18
|
+
|
19
|
+
```
|
20
|
+
rake js:routes
|
21
|
+
```
|
22
|
+
|
23
|
+
Make routes available globally in `app/javascript/packs/application.js`:
|
24
|
+
|
25
|
+
``` javascript
|
26
|
+
window.Routes = require('routes');
|
27
|
+
```
|
28
|
+
|
29
|
+
Individual routes can be imported using:
|
30
|
+
|
31
|
+
``` javascript
|
32
|
+
import {edit_post_path, new_post_path} from 'routes';
|
33
|
+
```
|
34
|
+
|
35
|
+
**Note**: that this setup requires `rake js:routes` to be run each time routes file is updated.
|
36
|
+
|
37
|
+
#### Webpacker + automatic updates
|
38
|
+
|
39
|
+
This setup can automatically update your routes without `rake js:routes` being called manually.
|
40
|
+
It requires [rails-erb-loader](https://github.com/usabilityhub/rails-erb-loader) npm package to work.
|
41
|
+
|
42
|
+
Add `erb` loader to webpacker:
|
43
|
+
|
44
|
+
``` sh
|
45
|
+
yarn add rails-erb-loader
|
46
|
+
rm -f app/javascript/routes.js # delete static file if any
|
47
|
+
```
|
48
|
+
|
49
|
+
Create webpack ERB config `config/webpack/loaders/erb.js`:
|
50
|
+
|
51
|
+
``` javascript
|
52
|
+
module.exports = {
|
53
|
+
test: /\.js\.erb$/,
|
54
|
+
enforce: 'pre',
|
55
|
+
exclude: /node_modules/,
|
56
|
+
use: [{
|
57
|
+
loader: 'rails-erb-loader',
|
58
|
+
options: {
|
59
|
+
runner: (/^win/.test(process.platform) ? 'ruby ' : '') + 'bin/rails runner'
|
60
|
+
}
|
61
|
+
}]
|
62
|
+
}
|
63
|
+
```
|
64
|
+
|
65
|
+
Enable `erb` extension in `config/webpacker/environment.js`:
|
66
|
+
|
67
|
+
```
|
68
|
+
const erb = require('./loaders/erb')
|
69
|
+
environment.loaders.append('erb', erb)
|
70
|
+
```
|
71
|
+
|
72
|
+
Create routes file `app/javascript/routes.js.erb`:
|
73
|
+
|
74
|
+
``` erb
|
75
|
+
<%= JsRoutes.generate() %>
|
76
|
+
```
|
77
|
+
|
78
|
+
Use routes wherever you need them `app/javascript/packs/application.js`:
|
79
|
+
|
80
|
+
``` javascript
|
81
|
+
window.Routes = require('routes.js.erb');
|
82
|
+
```
|
83
|
+
|
84
|
+
#### Sprockets (Deprecated)
|
85
|
+
|
86
|
+
If you are using [Sprockets](https://github.com/rails/sprockets-rails) you may configure js-routes in the following way.
|
87
|
+
|
88
|
+
Require JsRoutes in `app/assets/javascripts/application.js` or other bundle
|
18
89
|
|
19
90
|
``` js
|
20
91
|
//= require js-routes
|
@@ -32,7 +103,7 @@ This cache is not flushed on server restart in development environment.
|
|
32
103
|
|
33
104
|
### Configuration
|
34
105
|
|
35
|
-
You can configure JsRoutes in two main ways. Either with an initializer (e.g. `config/initializers/
|
106
|
+
You can configure JsRoutes in two main ways. Either with an initializer (e.g. `config/initializers/js_routes.rb`):
|
36
107
|
|
37
108
|
``` ruby
|
38
109
|
JsRoutes.setup do |config|
|
@@ -40,7 +111,7 @@ JsRoutes.setup do |config|
|
|
40
111
|
end
|
41
112
|
```
|
42
113
|
|
43
|
-
Or dynamically in JavaScript, although
|
114
|
+
Or dynamically in JavaScript, although only [Formatter Options](#formatter-options) are supported (see below)
|
44
115
|
|
45
116
|
``` js
|
46
117
|
Routes.configure({
|
@@ -49,93 +120,84 @@ Routes.configure({
|
|
49
120
|
Routes.config(); // current config
|
50
121
|
```
|
51
122
|
|
52
|
-
Available
|
123
|
+
#### Available Options
|
124
|
+
|
125
|
+
##### Generator Options
|
126
|
+
|
127
|
+
Options to configure JavaScript file generator. These options are only available in Ruby context but not JavaScript.
|
53
128
|
|
54
|
-
* `default_url_options` - default parameters used when generating URLs
|
55
|
-
* Option is configurable at JS level with `Routes.configure()`
|
56
|
-
* Example: {:format => "json", :trailing\_slash => true, :protocol => "https", :subdomain => "api", :host => "example.com", :port => 3000}
|
57
|
-
* Default: {}
|
58
129
|
* `exclude` - Array of regexps to exclude from routes.
|
59
|
-
* Default: []
|
130
|
+
* Default: `[]`
|
60
131
|
* The regexp applies only to the name before the `_path` suffix, eg: you want to match exactly `settings_path`, the regexp should be `/^settings$/`
|
61
132
|
* `include` - Array of regexps to include in routes.
|
62
|
-
* Default: []
|
133
|
+
* Default: `[]`
|
63
134
|
* The regexp applies only to the name before the `_path` suffix, eg: you want to match exactly `settings_path`, the regexp should be `/^settings$/`
|
64
135
|
* `namespace` - global object used to access routes.
|
65
136
|
* Supports nested namespace like `MyProject.routes`
|
66
137
|
* Default: `Routes`
|
67
|
-
* `
|
68
|
-
*
|
69
|
-
|
70
|
-
*
|
71
|
-
* `
|
72
|
-
* Default: false
|
73
|
-
* `url_links` (version >= 0.8.9) - Generate `*_url` helpers (in addition to the default `*_path` helpers).
|
74
|
-
* Example: true
|
75
|
-
* Default: false
|
138
|
+
* `camel_case` - Generate camel case route names.
|
139
|
+
* Default: `false`
|
140
|
+
* `url_links` - Generate `*_url` helpers (in addition to the default `*_path` helpers).
|
141
|
+
* Example: `true`
|
142
|
+
* Default: `false`
|
76
143
|
* Note: generated URLs will first use the protocol, host, and port options specified in the route definition. Otherwise, the URL will be based on the option specified in the `default_url_options` config. If no default option has been set, then the URL will fallback to the current URL based on `window.location`.
|
77
|
-
* `compact`
|
78
|
-
* Default: false
|
144
|
+
* `compact` - Remove `_path` suffix in path routes(`*_url` routes stay untouched if they were enabled)
|
145
|
+
* Default: `false`
|
79
146
|
* Sample route call when option is set to true: Routes.users() => `/users`
|
80
|
-
* `serializer` (version >= 1.1.0) - Puts a JS function here that serializes a Javascript Hash object into URL paramters: `{a: 1, b: 2} => "a=1&b=2"`.
|
81
|
-
* Default: `nil`. Uses built-in serializer
|
82
|
-
* Option is configurable at JS level with `Routes.configure()`
|
83
|
-
* Example: `jQuery.param` - use jQuery's serializer algorithm. You can attach serialize function from your favorite AJAX framework.
|
84
|
-
* Example: `MyApp.custom_serialize` - use completely custom serializer of your application.
|
85
|
-
|
86
|
-
* `special_options_key` - a special key that helps JsRoutes to destinguish serialized model from options hash
|
87
|
-
* This option is required because JS doesn't provide a difference between an object and a hash
|
88
|
-
* Option is configurable at JS level with `Routes.configure()`
|
89
|
-
* Default: `_options`
|
90
147
|
* `application` - a key to specify which rails engine you want to generate routes too.
|
91
148
|
* This option allows to only generate routes for a specific rails engine, that is mounted into routes instead of all Rails app routes
|
92
149
|
* Default: `Rails.application`
|
150
|
+
* `file` - a file location where generated routes are stored
|
151
|
+
* Default: `app/javascript/routes.js` if setup with Webpacker, otherwise `app/assets/javascripts/routes.js` if setup with Sprockets.
|
152
|
+
|
153
|
+
##### Formatter Options
|
154
|
+
|
155
|
+
Options to configure routes formatting. These options are available both in Ruby and JavaScript context.
|
93
156
|
|
94
|
-
|
157
|
+
* `default_url_options` - default parameters used when generating URLs
|
158
|
+
* Example: `{format: "json", trailing_slash: true, protocol: "https", subdomain: "api", host: "example.com", port: 3000}`
|
159
|
+
* Default: `{}`
|
160
|
+
* `prefix` - string that will prepend any generated URL. Usually used when app URL root includes a path component.
|
161
|
+
* Example: `/rails-app`
|
162
|
+
* Default: `Rails.application.config.relative_url_root`
|
163
|
+
* `serializer` - a JS function that serializes a Javascript Hash object into URL paramters like `{a: 1, b: 2} => "a=1&b=2"`.
|
164
|
+
* Default: `nil`. Uses built-in serializer compatible with Rails
|
165
|
+
* Example: `jQuery.param` - use jQuery's serializer algorithm. You can attach serialize function from your favorite AJAX framework.
|
166
|
+
* Example: `function (object) { ... }` - use completely custom serializer of your application.
|
167
|
+
* `special_options_key` - a special key that helps JsRoutes to destinguish serialized model from options hash
|
168
|
+
* This option exists because JS doesn't provide a difference between an object and a hash
|
169
|
+
* Default: `_options`
|
170
|
+
|
171
|
+
### Advanced Setup
|
95
172
|
|
96
173
|
In case you need multiple route files for different parts of your application, you have to create the files manually.
|
97
174
|
If your application has an `admin` and an `application` namespace for example:
|
98
175
|
|
99
176
|
```
|
100
|
-
# app/
|
177
|
+
# app/javascript/admin/routes.js.erb
|
101
178
|
<%= JsRoutes.generate(namespace: "AdminRoutes", include: /admin/) %>
|
102
|
-
|
103
|
-
# app/assets/javascripts/admin.js.coffee
|
104
|
-
#= require admin/routes
|
105
179
|
```
|
106
180
|
|
107
181
|
```
|
108
|
-
# app/
|
109
|
-
<%= JsRoutes.generate(namespace: "
|
110
|
-
|
111
|
-
# app/assets/javascripts/application.js.coffee
|
112
|
-
#= require application/routes
|
182
|
+
# app/javascript/customer/routes.js.erb
|
183
|
+
<%= JsRoutes.generate(namespace: "CustomerRoutes", exclude: /admin/) %>
|
113
184
|
```
|
114
185
|
|
115
186
|
In order to generate the routes JS code to a string:
|
116
187
|
|
117
|
-
```ruby
|
188
|
+
``` ruby
|
118
189
|
routes_js = JsRoutes.generate(options)
|
119
190
|
```
|
120
191
|
|
121
192
|
If you want to generate the routes files outside of the asset pipeline, you can use `JsRoutes.generate!`:
|
122
193
|
|
123
194
|
``` ruby
|
124
|
-
path = "app/
|
125
|
-
JsRoutes.generate!("#{path}/app_routes.js", :
|
126
|
-
JsRoutes.generate!("#{path}/adm_routes.js", :
|
127
|
-
JsRoutes.generate!("#{path}/api_routes.js", :
|
195
|
+
path = "app/javascript"
|
196
|
+
JsRoutes.generate!("#{path}/app_routes.js", namespace: "AppRoutes", exclude: [/^admin_/, /^api_/])
|
197
|
+
JsRoutes.generate!("#{path}/adm_routes.js", namespace: "AdmRoutes", include: /^admin_/)
|
198
|
+
JsRoutes.generate!("#{path}/api_routes.js", namespace: "ApiRoutes", include: /^api_/, default_url_options: {format: "json"})
|
128
199
|
```
|
129
200
|
|
130
|
-
### Rails relative URL root
|
131
|
-
|
132
|
-
If you've installed your application in a sub-path or sub-URI of your server instead of at the root, you need to set the `RAILS_RELATIVE_URL_ROOT` environment variable to the correct path prefix for your application when you precompile assets. Eg., if your application's base URL is "https://appl.example.com/Application1", the command to precompile assets would be:
|
133
|
-
```
|
134
|
-
RAILS_RELATIVE_URL_ROOT=/Application1 RAILS_ENV=production bundle exec rake assets:precompile
|
135
|
-
```
|
136
|
-
The environment variable is only needed for precompilation of assets, at any other time (eg. when assets are compiled on-the-fly as in the development environment) Rails will set the relative URL root correctly on it's own.
|
137
|
-
|
138
|
-
|
139
201
|
## Usage
|
140
202
|
|
141
203
|
Configuration above will create a nice javascript file with `Routes` object that has all the rails routes available:
|
@@ -206,7 +268,7 @@ Routes.company_project_path({company_id: 1, id: 2, _options: true}) // => "/comp
|
|
206
268
|
|
207
269
|
## What about security?
|
208
270
|
|
209
|
-
JsRoutes itself
|
271
|
+
JsRoutes itself does not have security holes. It makes URLs
|
210
272
|
without access protection more reachable by potential attacker.
|
211
273
|
In order to prevent this use `:exclude` option for sensitive urls like `/admin_/`
|
212
274
|
|
data/js-routes.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
|
|
21
21
|
s.summary = %q{Brings Rails named routes to javascript}
|
22
22
|
|
23
23
|
s.add_runtime_dependency(%q<railties>, [">= 4"])
|
24
|
-
s.
|
24
|
+
s.add_development_dependency(%q<sprockets-rails>)
|
25
25
|
s.add_development_dependency(%q<rspec>, [">= 3.0.0"])
|
26
26
|
s.add_development_dependency(%q<bundler>, [">= 1.1.0"])
|
27
27
|
s.add_development_dependency(%q<coffee-script>, [">= 0"])
|
data/lib/js_routes.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'uri'
|
2
|
-
|
2
|
+
if defined?(::Rails) && defined?(::Sprockets::Railtie)
|
3
|
+
require 'js_routes/engine'
|
4
|
+
end
|
3
5
|
require 'js_routes/version'
|
4
6
|
|
5
7
|
class JsRoutes
|
@@ -8,13 +10,17 @@ class JsRoutes
|
|
8
10
|
# OPTIONS
|
9
11
|
#
|
10
12
|
|
11
|
-
DEFAULT_PATH = File.join('app','assets','javascripts','routes.js')
|
12
|
-
|
13
13
|
DEFAULTS = {
|
14
|
-
namespace: "Routes",
|
14
|
+
namespace: -> { defined?(Webpacker) ? nil : "Routes" },
|
15
15
|
exclude: [],
|
16
16
|
include: //,
|
17
|
-
file:
|
17
|
+
file: -> do
|
18
|
+
webpacker_dir = Rails.root.join('app', 'javascript')
|
19
|
+
sprockets_dir = Rails.root.join('app','assets','javascripts')
|
20
|
+
sprockets_file = sprockets_dir.join('routes.js')
|
21
|
+
webpacker_file = webpacker_dir.join('routes.js')
|
22
|
+
!Dir.exists?(webpacker_dir) && defined?(::Sprockets) ? sprockets_file : webpacker_file
|
23
|
+
end,
|
18
24
|
prefix: -> { Rails.application.config.relative_url_root || "" },
|
19
25
|
url_links: false,
|
20
26
|
camel_case: false,
|
@@ -23,7 +29,7 @@ class JsRoutes
|
|
23
29
|
serializer: nil,
|
24
30
|
special_options_key: "_options",
|
25
31
|
application: -> { Rails.application }
|
26
|
-
}
|
32
|
+
} #:nodoc:
|
27
33
|
|
28
34
|
NODE_TYPES = {
|
29
35
|
GROUP: 1,
|
@@ -34,11 +40,11 @@ class JsRoutes
|
|
34
40
|
LITERAL: 6,
|
35
41
|
SLASH: 7,
|
36
42
|
DOT: 8
|
37
|
-
}
|
43
|
+
} #:nodoc:
|
38
44
|
|
39
|
-
LAST_OPTIONS_KEY = "options".freeze
|
40
|
-
FILTERED_DEFAULT_PARTS = [:controller, :action]
|
41
|
-
URL_OPTIONS = [:protocol, :domain, :host, :port, :subdomain]
|
45
|
+
LAST_OPTIONS_KEY = "options".freeze #:nodoc:
|
46
|
+
FILTERED_DEFAULT_PARTS = [:controller, :action] #:nodoc:
|
47
|
+
URL_OPTIONS = [:protocol, :domain, :host, :port, :subdomain] #:nodoc:
|
42
48
|
|
43
49
|
class Configuration < Struct.new(*DEFAULTS.keys)
|
44
50
|
def initialize(attributes = nil)
|
@@ -118,18 +124,18 @@ class JsRoutes
|
|
118
124
|
end
|
119
125
|
|
120
126
|
{
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
127
|
+
'GEM_VERSION' => JsRoutes::VERSION,
|
128
|
+
'ROUTES' => js_routes,
|
129
|
+
'NODE_TYPES' => json(NODE_TYPES),
|
130
|
+
'RAILS_VERSION' => ActionPack.version,
|
131
|
+
'DEPRECATED_GLOBBING_BEHAVIOR' => ActionPack::VERSION::MAJOR == 4 && ActionPack::VERSION::MINOR == 0,
|
132
|
+
|
133
|
+
'APP_CLASS' => application.class.to_s,
|
134
|
+
'NAMESPACE' => json(@configuration.namespace),
|
135
|
+
'DEFAULT_URL_OPTIONS' => json(@configuration.default_url_options),
|
136
|
+
'PREFIX' => json(@configuration.prefix),
|
137
|
+
'SPECIAL_OPTIONS_KEY' => json(@configuration.special_options_key),
|
138
|
+
'SERIALIZER' => @configuration.serializer || json(nil),
|
133
139
|
}.inject(File.read(File.dirname(__FILE__) + "/routes.js")) do |js, (key, value)|
|
134
140
|
js.gsub!(key, value.to_s)
|
135
141
|
end
|
@@ -146,7 +152,7 @@ class JsRoutes
|
|
146
152
|
|
147
153
|
# We don't need to rewrite file if it already exist and have same content.
|
148
154
|
# It helps asset pipeline or webpack understand that file wasn't changed.
|
149
|
-
|
155
|
+
next if File.exist?(file_path) && File.read(file_path) == js_content
|
150
156
|
|
151
157
|
File.open(file_path, 'w') do |f|
|
152
158
|
f.write js_content
|
@@ -173,7 +179,8 @@ class JsRoutes
|
|
173
179
|
|
174
180
|
def mounted_app_routes(route)
|
175
181
|
rails_engine_app = get_app_from_route(route)
|
176
|
-
if rails_engine_app.respond_to?(:superclass) &&
|
182
|
+
if rails_engine_app.respond_to?(:superclass) &&
|
183
|
+
rails_engine_app.superclass == Rails::Engine && !route.path.anchored
|
177
184
|
rails_engine_app.routes.named_routes.map do |_, engine_route|
|
178
185
|
build_route_if_match(engine_route, route)
|
179
186
|
end
|
@@ -183,7 +190,8 @@ class JsRoutes
|
|
183
190
|
end
|
184
191
|
|
185
192
|
def get_app_from_route(route)
|
186
|
-
# rails engine in Rails 4.2 use additional
|
193
|
+
# rails engine in Rails 4.2 use additional
|
194
|
+
# ActionDispatch::Routing::Mapper::Constraints, which contain app
|
187
195
|
if route.app.respond_to?(:app) && route.app.respond_to?(:constraints)
|
188
196
|
route.app.app
|
189
197
|
else
|
@@ -191,8 +199,9 @@ class JsRoutes
|
|
191
199
|
end
|
192
200
|
end
|
193
201
|
|
194
|
-
def build_route_if_match(route, parent_route=nil)
|
195
|
-
if any_match?(route, parent_route, @configuration[:exclude]) ||
|
202
|
+
def build_route_if_match(route, parent_route = nil)
|
203
|
+
if any_match?(route, parent_route, @configuration[:exclude]) ||
|
204
|
+
!any_match?(route, parent_route, @configuration[:include])
|
196
205
|
nil
|
197
206
|
else
|
198
207
|
build_js(route, parent_route)
|
@@ -203,7 +212,7 @@ class JsRoutes
|
|
203
212
|
full_route = [parent_route.try(:name), route.name].compact.join('_')
|
204
213
|
|
205
214
|
matchers = Array(matchers)
|
206
|
-
matchers.any? {|regex| full_route =~ regex}
|
215
|
+
matchers.any? { |regex| full_route =~ regex }
|
207
216
|
end
|
208
217
|
|
209
218
|
def build_js(route, parent_route)
|
@@ -211,8 +220,8 @@ class JsRoutes
|
|
211
220
|
route_name = generate_route_name(name, (:path unless @configuration[:compact]))
|
212
221
|
parent_spec = parent_route.try(:path).try(:spec)
|
213
222
|
route_arguments = route_js_arguments(route, parent_spec)
|
214
|
-
url_link = generate_url_link(name,
|
215
|
-
|
223
|
+
url_link = generate_url_link(name, route_arguments)
|
224
|
+
<<-JS.strip!
|
216
225
|
// #{name.join('.')} => #{parent_spec}#{route.path.spec}
|
217
226
|
// function(#{build_params(route.required_parts)})
|
218
227
|
#{route_name}: Utils.route(#{route_arguments})#{",\n" + url_link if url_link.length > 0}
|
@@ -225,7 +234,8 @@ class JsRoutes
|
|
225
234
|
hash[part] = required_parts.include?(part)
|
226
235
|
end
|
227
236
|
default_options = route.defaults.select do |part, _|
|
228
|
-
FILTERED_DEFAULT_PARTS.exclude?(part) &&
|
237
|
+
FILTERED_DEFAULT_PARTS.exclude?(part) &&
|
238
|
+
URL_OPTIONS.include?(part) || parts_table[part]
|
229
239
|
end
|
230
240
|
[
|
231
241
|
# JS objects don't preserve the order of properties which is crucial,
|
@@ -235,19 +245,19 @@ class JsRoutes
|
|
235
245
|
serialize(route.path.spec, parent_spec)
|
236
246
|
].map do |argument|
|
237
247
|
json(argument)
|
238
|
-
end.join(
|
248
|
+
end.join(', ')
|
239
249
|
end
|
240
250
|
|
241
|
-
def generate_url_link(name,
|
242
|
-
return
|
251
|
+
def generate_url_link(name, route_arguments)
|
252
|
+
return '' unless @configuration[:url_links]
|
253
|
+
|
243
254
|
<<-JS.strip!
|
244
255
|
#{generate_route_name(name, :url)}: Utils.route(#{route_arguments}, true)
|
245
256
|
JS
|
246
257
|
end
|
247
258
|
|
248
|
-
def generate_route_name(
|
249
|
-
route_name =
|
250
|
-
route_name << "_#{ suffix }" if suffix
|
259
|
+
def generate_route_name(*parts)
|
260
|
+
route_name = parts.compact.join('_')
|
251
261
|
@configuration[:camel_case] ? route_name.camelize(:lower) : route_name
|
252
262
|
end
|
253
263
|
|
@@ -257,7 +267,7 @@ class JsRoutes
|
|
257
267
|
|
258
268
|
def build_params(required_parts)
|
259
269
|
params = required_parts + [LAST_OPTIONS_KEY]
|
260
|
-
params.join(
|
270
|
+
params.join(', ')
|
261
271
|
end
|
262
272
|
|
263
273
|
# This function serializes Journey route into JSON structure
|
@@ -266,7 +276,9 @@ class JsRoutes
|
|
266
276
|
# Routes.js file will be smaller.
|
267
277
|
def serialize(spec, parent_spec=nil)
|
268
278
|
return nil unless spec
|
269
|
-
|
279
|
+
# Rails 4 globbing requires * removal
|
280
|
+
return spec.tr(':*', '') if spec.is_a?(String)
|
281
|
+
|
270
282
|
result = serialize_spec(spec, parent_spec)
|
271
283
|
if parent_spec && result[1].is_a?(String)
|
272
284
|
result = [
|
@@ -280,7 +292,7 @@ class JsRoutes
|
|
280
292
|
result
|
281
293
|
end
|
282
294
|
|
283
|
-
def serialize_spec(spec, parent_spec=nil)
|
295
|
+
def serialize_spec(spec, parent_spec = nil)
|
284
296
|
[
|
285
297
|
NODE_TYPES[spec.type],
|
286
298
|
serialize(spec.left, parent_spec),
|
@@ -288,4 +300,3 @@ class JsRoutes
|
|
288
300
|
]
|
289
301
|
end
|
290
302
|
end
|
291
|
-
|
data/lib/js_routes/engine.rb
CHANGED
@@ -47,7 +47,6 @@ class Engine < ::Rails::Engine
|
|
47
47
|
when -> (v) { v2.match?('', v) },
|
48
48
|
-> (v) { vgte3.match?('', v) }
|
49
49
|
|
50
|
-
# Other rails version, assumed newer
|
51
50
|
Rails.application.config.assets.configure do |config|
|
52
51
|
config.register_preprocessor(
|
53
52
|
"application/javascript",
|
data/lib/js_routes/version.rb
CHANGED
data/lib/routes.js
CHANGED
@@ -4,7 +4,7 @@ Based on Rails RAILS_VERSION routes of APP_CLASS
|
|
4
4
|
*/
|
5
5
|
|
6
6
|
(function() {
|
7
|
-
var DeprecatedGlobbingBehavior, NodeTypes, ParameterMissing, ReservedOptions, SpecialOptionsKey, UriEncoderSegmentRegex, Utils, root,
|
7
|
+
var DeprecatedGlobbingBehavior, NodeTypes, ParameterMissing, ReservedOptions, SpecialOptionsKey, UriEncoderSegmentRegex, Utils, result, root,
|
8
8
|
hasProp = {}.hasOwnProperty,
|
9
9
|
slice = [].slice;
|
10
10
|
|
@@ -336,9 +336,6 @@ Based on Rails RAILS_VERSION routes of APP_CLASS
|
|
336
336
|
visit_globbing: function(route, parameters, optional) {
|
337
337
|
var left, right, type, value;
|
338
338
|
type = route[0], left = route[1], right = route[2];
|
339
|
-
if (left.replace(/^\*/i, "") !== left) {
|
340
|
-
route[1] = left = left.replace(/^\*/i, "");
|
341
|
-
}
|
342
339
|
value = parameters[left];
|
343
340
|
delete parameters[left];
|
344
341
|
if (value == null) {
|
@@ -472,7 +469,7 @@ Based on Rails RAILS_VERSION routes of APP_CLASS
|
|
472
469
|
},
|
473
470
|
namespace: function(root, namespace, routes) {
|
474
471
|
var index, j, len, part, parts;
|
475
|
-
parts = namespace.split(".");
|
472
|
+
parts = namespace ? namespace.split(".") : [];
|
476
473
|
if (parts.length === 0) {
|
477
474
|
return routes;
|
478
475
|
}
|
@@ -500,25 +497,24 @@ Based on Rails RAILS_VERSION routes of APP_CLASS
|
|
500
497
|
routes.config = function() {
|
501
498
|
return Utils.config();
|
502
499
|
};
|
503
|
-
Object.defineProperty(routes, 'defaults', {
|
504
|
-
get: function() {
|
505
|
-
throw new Error(NAMESPACE + ".defaults is removed. Use " + NAMESPACE + ".configure() instead.");
|
506
|
-
},
|
507
|
-
set: function(value) {}
|
508
|
-
});
|
509
500
|
routes.default_serializer = function(object, prefix) {
|
510
501
|
return Utils.default_serializer(object, prefix);
|
511
502
|
};
|
512
|
-
|
503
|
+
Utils.namespace(root, NAMESPACE, routes);
|
504
|
+
return Object.assign({
|
505
|
+
"default": routes
|
506
|
+
}, routes);
|
513
507
|
}
|
514
508
|
};
|
515
509
|
|
510
|
+
result = Utils.make();
|
511
|
+
|
516
512
|
if (typeof define === "function" && define.amd) {
|
517
513
|
define([], function() {
|
518
|
-
return
|
514
|
+
return result;
|
519
515
|
});
|
520
|
-
} else {
|
521
|
-
Utils.make();
|
522
516
|
}
|
523
517
|
|
518
|
+
return result;
|
519
|
+
|
524
520
|
}).call(this);
|
data/lib/routes.js.coffee
CHANGED
@@ -258,8 +258,6 @@ Utils =
|
|
258
258
|
#
|
259
259
|
visit_globbing: (route, parameters, optional) ->
|
260
260
|
[type, left, right] = route
|
261
|
-
# fix for rails 4 globbing
|
262
|
-
route[1] = left = left.replace(/^\*/i, "") if left.replace(/^\*/i, "") isnt left
|
263
261
|
value = parameters[left]
|
264
262
|
delete parameters[left]
|
265
263
|
return @visit(route, parameters, optional) unless value?
|
@@ -377,7 +375,7 @@ Utils =
|
|
377
375
|
result
|
378
376
|
|
379
377
|
namespace: (root, namespace, routes) ->
|
380
|
-
parts = namespace.split(".")
|
378
|
+
parts = if namespace then namespace.split(".") else []
|
381
379
|
return routes if parts.length == 0
|
382
380
|
for part, index in parts
|
383
381
|
if index < parts.length - 1
|
@@ -395,19 +393,15 @@ Utils =
|
|
395
393
|
routes = ROUTES
|
396
394
|
routes.configure = (config) -> Utils.configure(config)
|
397
395
|
routes.config = -> Utils.config()
|
398
|
-
Object.defineProperty routes, 'defaults',
|
399
|
-
get: ->
|
400
|
-
throw new Error("#{NAMESPACE}.defaults is removed. Use #{NAMESPACE}.configure() instead.")
|
401
|
-
set: (value) ->
|
402
|
-
|
403
396
|
routes.default_serializer = (object, prefix) ->
|
404
397
|
Utils.default_serializer(object, prefix)
|
398
|
+
# Browser globals
|
405
399
|
Utils.namespace(root, NAMESPACE, routes)
|
400
|
+
Object.assign({default: routes}, routes)
|
406
401
|
|
402
|
+
result = Utils.make()
|
407
403
|
# Set up Routes appropriately for the environment.
|
408
404
|
if typeof define is "function" and define.amd
|
409
405
|
# AMD
|
410
|
-
define [], ->
|
411
|
-
|
412
|
-
# Browser globals
|
413
|
-
Utils.make()
|
406
|
+
define [], -> result
|
407
|
+
return result
|
@@ -39,4 +39,7 @@ EOF
|
|
39
39
|
expect(evaljs("require(['js-routes'], function(r){ return r.inboxes_path(); })")).to eq(test_routes.inboxes_path())
|
40
40
|
end
|
41
41
|
|
42
|
+
it "should define default export for es6 modules" do
|
43
|
+
expect(evaljs("require(['js-routes'], function(r){ return r.default.inboxes_path(); })")).to eq(test_routes.inboxes_path())
|
44
|
+
end
|
42
45
|
end
|
@@ -60,11 +60,6 @@ describe JsRoutes do
|
|
60
60
|
end
|
61
61
|
|
62
62
|
it "should not generate file before initialization" do
|
63
|
-
# This method is alread fixed in Rails master
|
64
|
-
# But in 3.2 stable we need to hack it like this
|
65
|
-
if Rails.application.instance_variable_get("@initialized")
|
66
|
-
pending
|
67
|
-
end
|
68
63
|
expect(File.exists?(name)).to be_falsey
|
69
64
|
end
|
70
65
|
|
@@ -167,36 +167,46 @@ describe JsRoutes, "options" do
|
|
167
167
|
expect(evaljs("Routes.no_format_path({format: 'json'})")).to eq(test_routes.no_format_path(format: 'json'))
|
168
168
|
end
|
169
169
|
|
170
|
-
describe "
|
170
|
+
describe "namespace option" do
|
171
171
|
let(:_options) { {:namespace => "PHM"} }
|
172
172
|
it "should use this namespace for routing" do
|
173
173
|
expect(evaljs("window.Routes")).to be_nil
|
174
174
|
expect(evaljs("PHM.inbox_path")).not_to be_nil
|
175
175
|
end
|
176
|
-
end
|
177
176
|
|
178
|
-
|
179
|
-
|
180
|
-
let(:_presetup) { "window.PHM = {}" }
|
181
|
-
let(:_options) { {:namespace => "PHM.Routes"} }
|
177
|
+
context "is nil" do
|
178
|
+
let(:_options) { {:namespace => nil} }
|
182
179
|
it "should use this namespace for routing" do
|
183
|
-
|
180
|
+
evaljs("window.zz = #{JsRoutes.generate(namespace: nil)}")
|
181
|
+
expect(evaljs("window.Routes")).to be_nil
|
182
|
+
expect(evaljs("window.zz.inbox_path")).not_to be_nil
|
184
183
|
end
|
184
|
+
|
185
185
|
end
|
186
186
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
187
|
+
describe "is nested" do
|
188
|
+
context "and defined on client" do
|
189
|
+
let(:_presetup) { "window.PHM = {}" }
|
190
|
+
let(:_options) { {:namespace => "PHM.Routes"} }
|
191
|
+
it "should use this namespace for routing" do
|
192
|
+
expect(evaljs("PHM.Routes.inbox_path")).not_to be_nil
|
193
|
+
end
|
191
194
|
end
|
192
|
-
end
|
193
195
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
196
|
+
context "but undefined on client" do
|
197
|
+
let(:_options) { {:namespace => "PHM.Routes"} }
|
198
|
+
it "should initialize namespace" do
|
199
|
+
expect(evaljs("window.PHM.Routes.inbox_path")).not_to be_nil
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
context "and some parts are defined" do
|
204
|
+
let(:_presetup) { "window.PHM = { Utils: {} };" }
|
205
|
+
let(:_options) { {:namespace => "PHM.Routes"} }
|
206
|
+
it "should not overwrite existing parts" do
|
207
|
+
expect(evaljs("window.PHM.Utils")).not_to be_nil
|
208
|
+
expect(evaljs("window.PHM.Routes.inbox_path")).not_to be_nil
|
209
|
+
end
|
200
210
|
end
|
201
211
|
end
|
202
212
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -95,11 +95,11 @@ RSpec.configure do |config|
|
|
95
95
|
|
96
96
|
if defined?(JRUBY_VERSION)
|
97
97
|
jscontext[:log] = lambda do |context, value|
|
98
|
-
puts value
|
98
|
+
puts value.inspect
|
99
99
|
end
|
100
100
|
else
|
101
101
|
jscontext.attach("log", proc do |value|
|
102
|
-
puts value
|
102
|
+
puts value.inspect
|
103
103
|
end)
|
104
104
|
end
|
105
105
|
end
|
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: 1.4.
|
4
|
+
version: 1.4.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bogdan Gusiev
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -31,7 +31,7 @@ dependencies:
|
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
|
-
type: :
|
34
|
+
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
@@ -172,6 +172,7 @@ files:
|
|
172
172
|
- lib/routes.js
|
173
173
|
- lib/routes.js.coffee
|
174
174
|
- lib/tasks/js_routes.rake
|
175
|
+
- spec/dummy/app/assets/config/manifest.js
|
175
176
|
- spec/dummy/app/assets/javascripts/.gitkeep
|
176
177
|
- spec/dummy/config/routes.rb
|
177
178
|
- spec/js_routes/amd_compatibility_spec.rb
|
@@ -186,7 +187,7 @@ homepage: http://github.com/railsware/js-routes
|
|
186
187
|
licenses:
|
187
188
|
- MIT
|
188
189
|
metadata: {}
|
189
|
-
post_install_message:
|
190
|
+
post_install_message:
|
190
191
|
rdoc_options: []
|
191
192
|
require_paths:
|
192
193
|
- lib
|
@@ -201,9 +202,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
201
202
|
- !ruby/object:Gem::Version
|
202
203
|
version: '0'
|
203
204
|
requirements: []
|
204
|
-
|
205
|
-
|
206
|
-
signing_key:
|
205
|
+
rubygems_version: 3.0.8
|
206
|
+
signing_key:
|
207
207
|
specification_version: 4
|
208
208
|
summary: Brings Rails named routes to javascript
|
209
209
|
test_files: []
|