js-routes 2.0.5 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/Readme.md +34 -22
- data/VERSION_2_UPGRADE.md +25 -20
- data/js-routes.gemspec +1 -1
- data/lib/js_routes/version.rb +1 -1
- data/lib/js_routes.rb +177 -99
- data/lib/routes.d.ts +64 -49
- data/lib/routes.js +60 -51
- data/lib/routes.ts +123 -84
- data/lib/tasks/js_routes.rake +8 -2
- data/package.json +2 -1
- data/spec/js_routes/default_serializer_spec.rb +1 -1
- data/spec/js_routes/module_types/dts/routes.spec.d.ts +114 -0
- data/spec/js_routes/module_types/dts/test.spec.ts +56 -0
- data/spec/js_routes/module_types/dts_spec.rb +111 -0
- data/spec/js_routes/options_spec.rb +5 -1
- data/spec/js_routes/rails_routes_compatibility_spec.rb +1 -1
- data/spec/js_routes/zzz_last_post_rails_init_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -1
- data/spec/tsconfig.json +4 -0
- data/tsconfig.json +4 -8
- metadata +8 -5
- data/lib/routes.js.map +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 242f329ab92abe8be4a2fa3790f72a3f161a6c2355b2392eae484a36a91d3a24
|
4
|
+
data.tar.gz: 120e5191eccfe3a8978c89ecb690a4f93a62279b249c58bc84b9273fe3e900c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e1998fd3c98dff227905bfcd8a09be8bb6901d3da7293b60d1a6f11c3a2627c623372324a13010cbe425eb7b93781fa64db042c08e7b4123d4a50ec8bd8814b2
|
7
|
+
data.tar.gz: 5395c808f148bd39a99de0ce748cbb3a57c27620f048764bfcf6a455ac6ce2bbc43e282f4c660ba019f8d4b5df39a316728bb673d56b2667aecb667dde82d91b
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
## master
|
2
2
|
|
3
|
+
## v2.1.0
|
4
|
+
|
5
|
+
* Support typescript defintions file aka `routes.d.ts`. See [Readme.md](./Readme.md#definitions) for more information.
|
6
|
+
|
7
|
+
## v2.0.8
|
8
|
+
|
9
|
+
* Forbid usage of `namespace` option if `module_type` is not `nil`. [#281](https://github.com/railsware/js-routes/issues/281).
|
10
|
+
|
11
|
+
## v2.0.7
|
12
|
+
|
13
|
+
* Remove source map annotation from JS file. Fixes [#277](https://github.com/railsware/js-routes/issues/277)
|
14
|
+
* Generated file is not minified, so it is better to use app side bundler/compressor for source maps
|
15
|
+
|
16
|
+
|
17
|
+
## v2.0.6
|
18
|
+
|
19
|
+
* Disable `namespace` option default for all envs [#278](https://github.com/railsware/js-routes/issues/278)
|
20
|
+
|
3
21
|
## v2.0.5
|
4
22
|
|
5
23
|
* Fixed backward compatibility issue [#276](https://github.com/railsware/js-routes/issues/276)
|
data/Readme.md
CHANGED
@@ -20,22 +20,26 @@ gem "js-routes"
|
|
20
20
|
|
21
21
|
Run:
|
22
22
|
|
23
|
-
```
|
23
|
+
``` sh
|
24
24
|
rake js:routes
|
25
|
+
# OR for typescript support
|
26
|
+
rake js:routes:typescript
|
25
27
|
```
|
26
28
|
|
27
|
-
|
29
|
+
|
30
|
+
Individual routes can be imported using:
|
28
31
|
|
29
32
|
``` javascript
|
30
|
-
import
|
31
|
-
|
33
|
+
import {edit_post_path, posts_path} from 'routes';
|
34
|
+
console.log(posts_path({format: 'json'})) // => "/posts.json"
|
35
|
+
console.log(edit_post_path(1)) // => "/posts/1/edit"
|
32
36
|
```
|
33
37
|
|
34
|
-
|
38
|
+
Make routes available globally in `app/javascript/packs/application.js`:
|
35
39
|
|
36
40
|
``` javascript
|
37
|
-
import
|
38
|
-
|
41
|
+
import * as Routes from 'routes';
|
42
|
+
window.Routes = Routes;
|
39
43
|
```
|
40
44
|
|
41
45
|
**Note**: that this setup requires `rake js:routes` to be run each time routes file is updated.
|
@@ -91,6 +95,22 @@ import * as Routes from 'routes.js.erb';
|
|
91
95
|
window.Routes = Routes;
|
92
96
|
```
|
93
97
|
|
98
|
+
<div id='definitions'></div>
|
99
|
+
|
100
|
+
#### Typescript Definitions
|
101
|
+
|
102
|
+
JsRoutes has typescript support out of the box. In order to generate typscript definitions file (aka `routes.d.ts`) you can call:
|
103
|
+
|
104
|
+
``` ruby
|
105
|
+
JsRoutes.definitions!
|
106
|
+
```
|
107
|
+
|
108
|
+
Or create an automatic updates file at `app/javascript/routes.d.ts.erb`:
|
109
|
+
|
110
|
+
``` erb
|
111
|
+
<%= JsRoutes.defintions %>
|
112
|
+
```
|
113
|
+
|
94
114
|
#### Sprockets (Deprecated)
|
95
115
|
|
96
116
|
If you are using [Sprockets](https://github.com/rails/sprockets-rails) you may configure js-routes in the following way.
|
@@ -147,7 +167,7 @@ Routes.config(); // current config
|
|
147
167
|
Options to configure JavaScript file generator. These options are only available in Ruby context but not JavaScript.
|
148
168
|
|
149
169
|
* `module_type` - JavaScript module type for generated code. [Article](https://dev.to/iggredible/what-the-heck-are-cjs-amd-umd-and-esm-ikm)
|
150
|
-
* Options: `ESM`, `UMD`, `CJS`, `AMD`, `nil`.
|
170
|
+
* Options: `ESM`, `UMD`, `CJS`, `AMD`, `DTS`, `nil`.
|
151
171
|
* Default: `ESM`
|
152
172
|
* `nil` option can be used in case you don't want generated code to export anything.
|
153
173
|
* `documentation` - specifies if each route should be annotated with [JSDoc](https://jsdoc.app/) comment
|
@@ -159,6 +179,7 @@ Options to configure JavaScript file generator. These options are only available
|
|
159
179
|
* Default: `[]`
|
160
180
|
* The regexp applies only to the name before the `_path` suffix, eg: you want to match exactly `settings_path`, the regexp should be `/^settings$/`
|
161
181
|
* `namespace` - global object used to access routes.
|
182
|
+
* Only available if `module_type` option is set to `nil`.
|
162
183
|
* Supports nested namespace like `MyProject.routes`
|
163
184
|
* Default: `nil`
|
164
185
|
* `camel_case` - specifies if route helpers should be generated in camel case instead of underscore case.
|
@@ -314,29 +335,20 @@ import {
|
|
314
335
|
} from 'routes.js.erb'
|
315
336
|
```
|
316
337
|
|
338
|
+
Such import structure allows for moddern JS bundlers like [Webpack](https://webpack.js.org/) to only include explicitly imported routes into JS bundle file.
|
339
|
+
See [Tree Shaking](https://webpack.js.org/guides/tree-shaking/) for more information.
|
340
|
+
|
317
341
|
### Exclude option
|
318
342
|
|
319
343
|
Split your routes into multiple files related to each section of your website like:
|
320
344
|
|
321
345
|
``` javascript
|
322
346
|
// admin-routes.js.erb
|
323
|
-
<%= JsRoutes.generate(include: /^admin_/)
|
347
|
+
<%= JsRoutes.generate(include: /^admin_/) %>
|
324
348
|
// app-routes.js.erb
|
325
|
-
<%= JsRoutes.generate(exclude: /^admin_/)
|
349
|
+
<%= JsRoutes.generate(exclude: /^admin_/) %>
|
326
350
|
```
|
327
351
|
|
328
|
-
## JsRoutes and Heroku
|
329
|
-
|
330
|
-
When using this setup on Heroku, it is impossible to use the asset pipeline. You should use the "Very Advanced Setup" schema in this case.
|
331
|
-
|
332
|
-
For example create routes.js.erb in assets folder with needed content:
|
333
|
-
|
334
|
-
``` erb
|
335
|
-
<%= JsRoutes.generate(options) %>
|
336
|
-
```
|
337
|
-
|
338
|
-
This should just work.
|
339
|
-
|
340
352
|
## Advantages over alternatives
|
341
353
|
|
342
354
|
There are some alternatives available. Most of them has only basic feature and don't reach the level of quality I accept.
|
data/VERSION_2_UPGRADE.md
CHANGED
@@ -2,23 +2,40 @@
|
|
2
2
|
|
3
3
|
### Using ESM module by default
|
4
4
|
|
5
|
-
|
5
|
+
New version of JsRoutes doesn't try to guess your javascript environment module system because JS has generated a ton of legacy module systems in the past.
|
6
|
+
[ESM+Webpacker](/Readme.md#webpacker) upgrade is recommended.
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
module\_type | nil | ESM
|
10
|
-
namespace | Routes | nil
|
8
|
+
However, if you don't want to follow that pass, specify `module_type` configuration option instead based on module system available in your JS environment.
|
9
|
+
Here are supported values:
|
11
10
|
|
12
|
-
|
11
|
+
* CJS
|
12
|
+
* UMD
|
13
|
+
* AMD
|
14
|
+
* ESM
|
15
|
+
* nil
|
16
|
+
|
17
|
+
[Explaination Article](https://dev.to/iggredible/what-the-heck-are-cjs-amd-umd-and-esm-ikm)
|
18
|
+
|
19
|
+
If you don't want to use any JS module system and make routes available via a **global variable**, specify `nil` as a `module_type` and use `namespace` option:
|
13
20
|
|
14
21
|
``` ruby
|
15
22
|
JsRoutes.setup do |config|
|
16
23
|
config.module_type = nil
|
17
|
-
config.namespace =
|
24
|
+
config.namespace = "Routes"
|
18
25
|
end
|
19
26
|
```
|
20
27
|
|
21
|
-
|
28
|
+
### JSDoc comment
|
29
|
+
|
30
|
+
New version of js-routes generates function comment in the [JSDoc](https://jsdoc.app) format.
|
31
|
+
If you have any problems with that, you can disable it like this:
|
32
|
+
|
33
|
+
|
34
|
+
``` ruby
|
35
|
+
JsRoutes.setup do |config|
|
36
|
+
config.documentation = false
|
37
|
+
end
|
38
|
+
```
|
22
39
|
|
23
40
|
### `required_params` renamed
|
24
41
|
|
@@ -47,15 +64,3 @@ try {
|
|
47
64
|
}
|
48
65
|
}
|
49
66
|
```
|
50
|
-
|
51
|
-
### JSDoc comment format
|
52
|
-
|
53
|
-
New version of js-routes generates function comment in the [JSDoc](https://jsdoc.app) format.
|
54
|
-
If you have any problems with that disable the annotation:
|
55
|
-
|
56
|
-
``` ruby
|
57
|
-
JsRoutes.setup do |config|
|
58
|
-
config.documentation = false
|
59
|
-
end
|
60
|
-
```
|
61
|
-
|
data/js-routes.gemspec
CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |s|
|
|
25
25
|
|
26
26
|
s.add_runtime_dependency(%q<railties>, [">= 4"])
|
27
27
|
s.add_development_dependency(%q<sprockets-rails>)
|
28
|
-
s.add_development_dependency(%q<rspec>, [">= 3.
|
28
|
+
s.add_development_dependency(%q<rspec>, [">= 3.10.0"])
|
29
29
|
s.add_development_dependency(%q<bundler>, [">= 1.1.0"])
|
30
30
|
s.add_development_dependency(%q<appraisal>, [">= 0.5.2"])
|
31
31
|
s.add_development_dependency(%q<bump>, [">= 0.10.0"])
|
data/lib/js_routes/version.rb
CHANGED
data/lib/js_routes.rb
CHANGED
@@ -7,48 +7,26 @@ require 'active_support/core_ext/string/indent'
|
|
7
7
|
|
8
8
|
class JsRoutes
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
class Configuration
|
11
|
+
DEFAULTS = {
|
12
|
+
namespace: nil,
|
13
|
+
exclude: [],
|
14
|
+
include: //,
|
15
|
+
file: nil,
|
16
|
+
prefix: -> { Rails.application.config.relative_url_root || "" },
|
17
|
+
url_links: false,
|
18
|
+
camel_case: false,
|
19
|
+
default_url_options: {},
|
20
|
+
compact: false,
|
21
|
+
serializer: nil,
|
22
|
+
special_options_key: "_options",
|
23
|
+
application: -> { Rails.application },
|
24
|
+
module_type: 'ESM',
|
25
|
+
documentation: true,
|
26
|
+
} #:nodoc:
|
27
|
+
|
28
|
+
attr_accessor(*DEFAULTS.keys)
|
13
29
|
|
14
|
-
DEFAULTS = {
|
15
|
-
namespace: -> { defined?(Webpacker) ? nil : "Routes" },
|
16
|
-
exclude: [],
|
17
|
-
include: //,
|
18
|
-
file: -> do
|
19
|
-
webpacker_dir = Rails.root.join('app', 'javascript')
|
20
|
-
sprockets_dir = Rails.root.join('app','assets','javascripts')
|
21
|
-
sprockets_file = sprockets_dir.join('routes.js')
|
22
|
-
webpacker_file = webpacker_dir.join('routes.js')
|
23
|
-
!Dir.exist?(webpacker_dir) && defined?(::Sprockets) ? sprockets_file : webpacker_file
|
24
|
-
end,
|
25
|
-
prefix: -> { Rails.application.config.relative_url_root || "" },
|
26
|
-
url_links: false,
|
27
|
-
camel_case: false,
|
28
|
-
default_url_options: {},
|
29
|
-
compact: false,
|
30
|
-
serializer: nil,
|
31
|
-
special_options_key: "_options",
|
32
|
-
application: -> { Rails.application },
|
33
|
-
module_type: 'ESM',
|
34
|
-
documentation: true,
|
35
|
-
} #:nodoc:
|
36
|
-
|
37
|
-
NODE_TYPES = {
|
38
|
-
GROUP: 1,
|
39
|
-
CAT: 2,
|
40
|
-
SYMBOL: 3,
|
41
|
-
OR: 4,
|
42
|
-
STAR: 5,
|
43
|
-
LITERAL: 6,
|
44
|
-
SLASH: 7,
|
45
|
-
DOT: 8
|
46
|
-
} #:nodoc:
|
47
|
-
|
48
|
-
FILTERED_DEFAULT_PARTS = [:controller, :action] #:nodoc:
|
49
|
-
URL_OPTIONS = [:protocol, :domain, :host, :port, :subdomain] #:nodoc:
|
50
|
-
|
51
|
-
class Configuration < Struct.new(*DEFAULTS.keys)
|
52
30
|
def initialize(attributes = nil)
|
53
31
|
assign(DEFAULTS)
|
54
32
|
return unless attributes
|
@@ -60,6 +38,7 @@ class JsRoutes
|
|
60
38
|
value = value.call if value.is_a?(Proc)
|
61
39
|
send(:"#{attribute}=", value)
|
62
40
|
end
|
41
|
+
normalize_and_verify
|
63
42
|
self
|
64
43
|
end
|
65
44
|
|
@@ -76,7 +55,49 @@ class JsRoutes
|
|
76
55
|
end
|
77
56
|
|
78
57
|
def esm?
|
79
|
-
|
58
|
+
module_type === 'ESM'
|
59
|
+
end
|
60
|
+
|
61
|
+
def dts?
|
62
|
+
self.module_type === 'DTS'
|
63
|
+
end
|
64
|
+
|
65
|
+
def modern?
|
66
|
+
esm? || dts?
|
67
|
+
end
|
68
|
+
|
69
|
+
def source_file
|
70
|
+
File.dirname(__FILE__) + "/" + default_file_name
|
71
|
+
end
|
72
|
+
|
73
|
+
def output_file
|
74
|
+
webpacker_dir = Rails.root.join('app', 'javascript')
|
75
|
+
sprockets_dir = Rails.root.join('app','assets','javascripts')
|
76
|
+
file_name = file || default_file_name
|
77
|
+
sprockets_file = sprockets_dir.join(file_name)
|
78
|
+
webpacker_file = webpacker_dir.join(file_name)
|
79
|
+
!Dir.exist?(webpacker_dir) && defined?(::Sprockets) ? sprockets_file : webpacker_file
|
80
|
+
end
|
81
|
+
|
82
|
+
def normalize_and_verify
|
83
|
+
normalize
|
84
|
+
verify
|
85
|
+
end
|
86
|
+
|
87
|
+
protected
|
88
|
+
|
89
|
+
def default_file_name
|
90
|
+
dts? ? "routes.d.ts" : "routes.js"
|
91
|
+
end
|
92
|
+
|
93
|
+
def normalize
|
94
|
+
self.module_type = module_type&.upcase || 'NIL'
|
95
|
+
end
|
96
|
+
|
97
|
+
def verify
|
98
|
+
if module_type != 'NIL' && namespace
|
99
|
+
raise "JsRoutes namespace option can only be used if module_type is nil"
|
100
|
+
end
|
80
101
|
end
|
81
102
|
end
|
82
103
|
|
@@ -87,6 +108,7 @@ class JsRoutes
|
|
87
108
|
class << self
|
88
109
|
def setup(&block)
|
89
110
|
configuration.tap(&block) if block
|
111
|
+
configuration.normalize_and_verify
|
90
112
|
end
|
91
113
|
|
92
114
|
def configuration
|
@@ -97,12 +119,13 @@ class JsRoutes
|
|
97
119
|
new(opts).generate
|
98
120
|
end
|
99
121
|
|
100
|
-
def generate!(file_name=nil, opts
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
122
|
+
def generate!(file_name=nil, **opts)
|
123
|
+
new(file: file_name, **opts).generate!
|
124
|
+
end
|
125
|
+
|
126
|
+
def definitions!(file_name = nil, **opts)
|
127
|
+
file_name ||= configuration.file&.sub!(%r{\.(j|t)s\Z}, ".d.ts")
|
128
|
+
new(file: file_name, module_type: 'DTS', **opts).generate!
|
106
129
|
end
|
107
130
|
|
108
131
|
def json(string)
|
@@ -123,48 +146,55 @@ class JsRoutes
|
|
123
146
|
if named_routes.to_a.empty? && application.respond_to?(:reload_routes!)
|
124
147
|
application.reload_routes!
|
125
148
|
end
|
149
|
+
content = File.read(@configuration.source_file)
|
126
150
|
|
127
|
-
|
128
|
-
|
129
|
-
|
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),
|
139
|
-
'MODULE_TYPE' => json(@configuration.module_type),
|
140
|
-
'WRAPPER' => @configuration.esm? ? 'const __jsr = ' : '',
|
141
|
-
}.inject(File.read(File.dirname(__FILE__) + "/routes.js")) do |js, (key, value)|
|
142
|
-
js.gsub!("RubyVariables.#{key}", value.to_s) ||
|
151
|
+
if !@configuration.dts?
|
152
|
+
content = js_variables.inject(content) do |js, (key, value)|
|
153
|
+
js.gsub!("RubyVariables.#{key}", value.to_s) ||
|
143
154
|
raise("Missing key #{key} in JS template")
|
144
|
-
|
155
|
+
end
|
156
|
+
end
|
157
|
+
content + routes_export + prevent_types_export
|
145
158
|
end
|
146
159
|
|
147
|
-
def generate!
|
148
|
-
# Some libraries like Devise
|
149
|
-
# until initialization process
|
160
|
+
def generate!
|
161
|
+
# Some libraries like Devise did not load their routes yet
|
162
|
+
# so we will wait until initialization process finishes
|
150
163
|
# https://github.com/railsware/js-routes/issues/7
|
151
164
|
Rails.configuration.after_initialize do
|
152
|
-
|
153
|
-
|
154
|
-
js_content = generate
|
165
|
+
file_path = Rails.root.join(@configuration.output_file)
|
166
|
+
source_code = generate
|
155
167
|
|
156
168
|
# We don't need to rewrite file if it already exist and have same content.
|
157
169
|
# It helps asset pipeline or webpack understand that file wasn't changed.
|
158
|
-
next if File.exist?(file_path) && File.read(file_path) ==
|
170
|
+
next if File.exist?(file_path) && File.read(file_path) == source_code
|
159
171
|
|
160
172
|
File.open(file_path, 'w') do |f|
|
161
|
-
f.write
|
173
|
+
f.write source_code
|
162
174
|
end
|
163
175
|
end
|
164
176
|
end
|
165
177
|
|
166
178
|
protected
|
167
179
|
|
180
|
+
def js_variables
|
181
|
+
{
|
182
|
+
'GEM_VERSION' => JsRoutes::VERSION,
|
183
|
+
'ROUTES_OBJECT' => routes_object,
|
184
|
+
'RAILS_VERSION' => ActionPack.version,
|
185
|
+
'DEPRECATED_GLOBBING_BEHAVIOR' => ActionPack::VERSION::MAJOR == 4 && ActionPack::VERSION::MINOR == 0,
|
186
|
+
|
187
|
+
'APP_CLASS' => application.class.to_s,
|
188
|
+
'NAMESPACE' => json(@configuration.namespace),
|
189
|
+
'DEFAULT_URL_OPTIONS' => json(@configuration.default_url_options),
|
190
|
+
'PREFIX' => json(@configuration.prefix),
|
191
|
+
'SPECIAL_OPTIONS_KEY' => json(@configuration.special_options_key),
|
192
|
+
'SERIALIZER' => @configuration.serializer || json(nil),
|
193
|
+
'MODULE_TYPE' => json(@configuration.module_type),
|
194
|
+
'WRAPPER' => @configuration.esm? ? 'const __jsr = ' : '',
|
195
|
+
}
|
196
|
+
end
|
197
|
+
|
168
198
|
def application
|
169
199
|
@configuration.application
|
170
200
|
end
|
@@ -178,32 +208,52 @@ class JsRoutes
|
|
178
208
|
end
|
179
209
|
|
180
210
|
def routes_object
|
181
|
-
return json({}) if @configuration.
|
211
|
+
return json({}) if @configuration.modern?
|
182
212
|
properties = routes_list.map do |comment, name, body|
|
183
213
|
"#{comment}#{name}: #{body}".indent(2)
|
184
214
|
end
|
185
215
|
"{\n" + properties.join(",\n\n") + "}\n"
|
186
216
|
end
|
187
217
|
|
188
|
-
|
189
|
-
[
|
218
|
+
def static_exports
|
219
|
+
[:configure, :config, :serialize].map do |name|
|
220
|
+
[
|
221
|
+
"", name,
|
222
|
+
@configuration.dts? ?
|
223
|
+
"RouterExposedMethods['#{name}']" :
|
224
|
+
"__jsr.#{name}"
|
225
|
+
]
|
226
|
+
end
|
190
227
|
end
|
191
228
|
|
192
229
|
def routes_export
|
193
|
-
return "" unless @configuration.
|
194
|
-
[*
|
195
|
-
"#{comment}export const #{name}
|
196
|
-
end.join
|
230
|
+
return "" unless @configuration.modern?
|
231
|
+
[*static_exports, *routes_list].map do |comment, name, body|
|
232
|
+
"#{comment}export const #{name}#{export_separator}#{body};\n\n"
|
233
|
+
end.join
|
234
|
+
end
|
235
|
+
|
236
|
+
def prevent_types_export
|
237
|
+
return "" unless @configuration.dts?
|
238
|
+
<<-JS
|
239
|
+
// By some reason this line prevents all types in a file
|
240
|
+
// from being automatically exported
|
241
|
+
export {};
|
242
|
+
JS
|
243
|
+
end
|
244
|
+
|
245
|
+
def export_separator
|
246
|
+
@configuration.dts? ? ': ' : ' = '
|
197
247
|
end
|
198
248
|
|
199
249
|
def routes_list
|
200
250
|
named_routes.sort_by(&:first).flat_map do |_, route|
|
201
251
|
route_helpers_if_match(route) + mounted_app_routes(route)
|
202
|
-
end
|
252
|
+
end
|
203
253
|
end
|
204
254
|
|
205
255
|
def mounted_app_routes(route)
|
206
|
-
rails_engine_app =
|
256
|
+
rails_engine_app = app_from_route(route)
|
207
257
|
if rails_engine_app.respond_to?(:superclass) &&
|
208
258
|
rails_engine_app.superclass == Rails::Engine && !route.path.anchored
|
209
259
|
rails_engine_app.routes.named_routes.flat_map do |_, engine_route|
|
@@ -214,7 +264,7 @@ class JsRoutes
|
|
214
264
|
end
|
215
265
|
end
|
216
266
|
|
217
|
-
def
|
267
|
+
def app_from_route(route)
|
218
268
|
# rails engine in Rails 4.2 use additional
|
219
269
|
# ActionDispatch::Routing::Mapper::Constraints, which contain app
|
220
270
|
if route.app.respond_to?(:app) && route.app.respond_to?(:constraints)
|
@@ -229,6 +279,19 @@ class JsRoutes
|
|
229
279
|
end
|
230
280
|
|
231
281
|
class JsRoute #:nodoc:
|
282
|
+
FILTERED_DEFAULT_PARTS = [:controller, :action]
|
283
|
+
URL_OPTIONS = [:protocol, :domain, :host, :port, :subdomain]
|
284
|
+
NODE_TYPES = {
|
285
|
+
GROUP: 1,
|
286
|
+
CAT: 2,
|
287
|
+
SYMBOL: 3,
|
288
|
+
OR: 4,
|
289
|
+
STAR: 5,
|
290
|
+
LITERAL: 6,
|
291
|
+
SLASH: 7,
|
292
|
+
DOT: 8
|
293
|
+
}
|
294
|
+
|
232
295
|
attr_reader :configuration, :route, :parent_route
|
233
296
|
|
234
297
|
def initialize(configuration, route, parent_route = nil)
|
@@ -238,22 +301,36 @@ class JsRoutes
|
|
238
301
|
end
|
239
302
|
|
240
303
|
def helpers
|
241
|
-
|
242
|
-
[]
|
243
|
-
else
|
244
|
-
[false, true].map do |absolute|
|
245
|
-
absolute && !@configuration[:url_links] ?
|
246
|
-
nil : [ documentation, helper_name(absolute), body(absolute) ]
|
247
|
-
end
|
304
|
+
helper_types.map do |absolute|
|
305
|
+
[ documentation, helper_name(absolute), body(absolute) ]
|
248
306
|
end
|
249
307
|
end
|
250
308
|
|
309
|
+
def helper_types
|
310
|
+
return [] unless match_configuration?
|
311
|
+
@configuration[:url_links] ? [true, false] : [false]
|
312
|
+
end
|
313
|
+
|
251
314
|
def body(absolute)
|
252
|
-
|
315
|
+
@configuration.dts? ?
|
316
|
+
definition_body : "__jsr.r(#{arguments(absolute).map{|a| json(a)}.join(', ')})"
|
317
|
+
end
|
318
|
+
|
319
|
+
def definition_body
|
320
|
+
args = required_parts.map{|p| "#{apply_case(p)}: RequiredRouteParameter"}
|
321
|
+
args << "options?: #{optional_parts_type} & RouteOptions"
|
322
|
+
"((\n#{args.join(",\n").indent(2)}\n) => string) & RouteHelperExtras"
|
323
|
+
end
|
324
|
+
|
325
|
+
def optional_parts_type
|
326
|
+
@optional_parts_type ||=
|
327
|
+
"{" + optional_parts.map {|p| "#{p}?: OptionalRouteParameter"}.join(', ') + "}"
|
253
328
|
end
|
254
329
|
|
330
|
+
protected
|
331
|
+
|
255
332
|
def arguments(absolute)
|
256
|
-
absolute ? base_arguments
|
333
|
+
absolute ? [*base_arguments, true] : base_arguments
|
257
334
|
end
|
258
335
|
|
259
336
|
def match_configuration?
|
@@ -298,10 +375,15 @@ JS
|
|
298
375
|
route.required_parts
|
299
376
|
end
|
300
377
|
|
301
|
-
|
378
|
+
def optional_parts
|
379
|
+
route.path.optional_names
|
380
|
+
end
|
302
381
|
|
303
382
|
def base_arguments
|
304
|
-
|
383
|
+
@base_arguments ||= [parts_table, serialize(spec, parent_spec)]
|
384
|
+
end
|
385
|
+
|
386
|
+
def parts_table
|
305
387
|
parts_table = {}
|
306
388
|
route.parts.each do |part, hash|
|
307
389
|
parts_table[part] ||= {}
|
@@ -318,11 +400,7 @@ JS
|
|
318
400
|
parts_table[part][:d] = value
|
319
401
|
end
|
320
402
|
end
|
321
|
-
|
322
|
-
parts_table, serialize(spec, parent_spec)
|
323
|
-
].map do |argument|
|
324
|
-
json(argument)
|
325
|
-
end
|
403
|
+
parts_table
|
326
404
|
end
|
327
405
|
|
328
406
|
def documentation_params
|