js-routes 2.2.1 → 2.2.4
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 +19 -0
- data/Readme.md +2 -1
- data/lib/js_routes/configuration.rb +111 -0
- data/lib/js_routes/engine.rb +28 -26
- data/lib/js_routes/generators/middleware.rb +1 -1
- data/lib/js_routes/instance.rb +173 -0
- data/lib/js_routes/middleware.rb +7 -3
- data/lib/js_routes/route.rb +1 -1
- data/lib/js_routes/version.rb +2 -2
- data/lib/js_routes.rb +8 -261
- data/lib/routes.d.ts +1 -1
- data/lib/routes.js +22 -27
- data/lib/routes.ts +21 -32
- data/spec/js_routes/default_serializer_spec.rb +4 -4
- data/spec/js_routes/module_types/amd_spec.rb +1 -1
- data/spec/js_routes/module_types/cjs_spec.rb +1 -1
- data/spec/js_routes/module_types/dts/routes.spec.d.ts +1 -1
- data/spec/js_routes/module_types/esm_spec.rb +2 -2
- data/spec/js_routes/module_types/nil_spec.rb +8 -7
- data/spec/js_routes/options_spec.rb +85 -82
- data/spec/js_routes/rails_routes_compatibility_spec.rb +127 -137
- data/spec/js_routes/route_specification_spec.rb +40 -0
- data/spec/spec_helper.rb +16 -4
- 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: 66ff94f5c78d966f76e2a9f47d1c838c757c3e243c37f03599b24c286b15b9b7
|
4
|
+
data.tar.gz: c5803e4a35b99923769970149f07a6893a84c6343f10f76c8a89645974dce959
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a34c75f950a02a6634687889e4072f7d88f37520a6dc2ba5bfd2ccbbb71962159a70170bf7ac55b22db45de2727f7c573dfce8c80debc33f34abbd9cb1132c1f
|
7
|
+
data.tar.gz: 779b340c9dac721c8b427a16011ed961a05dde4d15594838649fb0860bac42e60344a682718a0b94f35f785350126ca59c7f739dac43cb47e0a7b84e45fa468a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,24 @@
|
|
1
1
|
## master
|
2
2
|
|
3
|
+
## v2.2.5
|
4
|
+
|
5
|
+
* Fix middleware generator [#300](https://github.com/railsware/js-routes/issues/300)
|
6
|
+
* Support `params` special parameter
|
7
|
+
|
8
|
+
## v2.2.4
|
9
|
+
|
10
|
+
* Fix rails engine loading if sprockets is not in Gemfile. Fixes [#294](https://github.com/railsware/js-routes/issues/294)
|
11
|
+
|
12
|
+
## v2.2.3
|
13
|
+
|
14
|
+
* Fixed NIL module type namespace defintion [#297](https://github.com/railsware/js-routes/issues/297).
|
15
|
+
* The patch may cause a problem with nested `namespace` option
|
16
|
+
* Ex. Value like `MyProject.Routes` requires to define `window.MyProject` before importing the routes file
|
17
|
+
|
18
|
+
## v2.2.2.
|
19
|
+
|
20
|
+
* Fix custom file path [#295](https://github.com/railsware/js-routes/issues/295)
|
21
|
+
|
3
22
|
## v2.2.1
|
4
23
|
|
5
24
|
* Improve generator to update route files on `assets:precompile` and add them to `.gitignore by default` [#288](https://github.com/railsware/js-routes/issues/288#issuecomment-1012182815)
|
data/Readme.md
CHANGED
@@ -20,6 +20,7 @@ There are several 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
|
+
* Automatically generates routes files on `assets:precompile` in production
|
23
24
|
* Works great for a simple Rails application
|
24
25
|
* [Webpacker ERB Loader](#webpacker)
|
25
26
|
* Requires ESM module system (the default)
|
@@ -61,7 +62,7 @@ import * as Routes from '../routes';
|
|
61
62
|
alert(Routes.post_path(1))
|
62
63
|
```
|
63
64
|
|
64
|
-
Upgrade `rake assets:precompile` to update js-routes files
|
65
|
+
Upgrade `rake assets:precompile` to update js-routes files in `Rakefile`:
|
65
66
|
|
66
67
|
``` ruby
|
67
68
|
namespace :assets do
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require "pathname"
|
2
|
+
|
3
|
+
module JsRoutes
|
4
|
+
class Configuration
|
5
|
+
DEFAULTS = {
|
6
|
+
namespace: nil,
|
7
|
+
exclude: [],
|
8
|
+
include: //,
|
9
|
+
file: nil,
|
10
|
+
prefix: -> { Rails.application.config.relative_url_root || "" },
|
11
|
+
url_links: false,
|
12
|
+
camel_case: false,
|
13
|
+
default_url_options: {},
|
14
|
+
compact: false,
|
15
|
+
serializer: nil,
|
16
|
+
special_options_key: "_options",
|
17
|
+
application: -> { Rails.application },
|
18
|
+
module_type: 'ESM',
|
19
|
+
documentation: true,
|
20
|
+
} #:nodoc:
|
21
|
+
|
22
|
+
attr_accessor(*DEFAULTS.keys)
|
23
|
+
|
24
|
+
def initialize(attributes = nil)
|
25
|
+
assign(DEFAULTS)
|
26
|
+
return unless attributes
|
27
|
+
assign(attributes)
|
28
|
+
end
|
29
|
+
|
30
|
+
def assign(attributes = nil, &block)
|
31
|
+
if !attributes && !block
|
32
|
+
raise "Provide attributes or block"
|
33
|
+
end
|
34
|
+
tap(&block) if block
|
35
|
+
if attributes
|
36
|
+
attributes.each do |attribute, value|
|
37
|
+
value = value.call if value.is_a?(Proc)
|
38
|
+
send(:"#{attribute}=", value)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
normalize_and_verify
|
42
|
+
self
|
43
|
+
end
|
44
|
+
|
45
|
+
def [](attribute)
|
46
|
+
send(attribute)
|
47
|
+
end
|
48
|
+
|
49
|
+
def merge(attributes)
|
50
|
+
clone.assign(attributes)
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_hash
|
54
|
+
Hash[*members.zip(values).flatten(1)].symbolize_keys
|
55
|
+
end
|
56
|
+
|
57
|
+
def esm?
|
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 require_esm
|
70
|
+
raise "ESM module type is required" unless modern?
|
71
|
+
end
|
72
|
+
|
73
|
+
def source_file
|
74
|
+
File.dirname(__FILE__) + "/../" + default_file_name
|
75
|
+
end
|
76
|
+
|
77
|
+
def output_file
|
78
|
+
webpacker_dir = pathname('app', 'javascript')
|
79
|
+
sprockets_dir = pathname('app','assets','javascripts')
|
80
|
+
file_name = file || default_file_name
|
81
|
+
sprockets_file = sprockets_dir.join(file_name)
|
82
|
+
webpacker_file = webpacker_dir.join(file_name)
|
83
|
+
!Dir.exist?(webpacker_dir) && defined?(::Sprockets) ? sprockets_file : webpacker_file
|
84
|
+
end
|
85
|
+
|
86
|
+
protected
|
87
|
+
|
88
|
+
def normalize_and_verify
|
89
|
+
normalize
|
90
|
+
verify
|
91
|
+
end
|
92
|
+
|
93
|
+
def pathname(*parts)
|
94
|
+
Pathname.new(File.join(*parts))
|
95
|
+
end
|
96
|
+
|
97
|
+
def default_file_name
|
98
|
+
dts? ? "routes.d.ts" : "routes.js"
|
99
|
+
end
|
100
|
+
|
101
|
+
def normalize
|
102
|
+
self.module_type = module_type&.upcase || 'NIL'
|
103
|
+
end
|
104
|
+
|
105
|
+
def verify
|
106
|
+
if module_type != 'NIL' && namespace
|
107
|
+
raise "JsRoutes namespace option can only be used if module_type is nil"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/lib/js_routes/engine.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
module JsRoutes
|
2
2
|
class SprocketsExtension
|
3
3
|
def initialize(filename, &block)
|
4
4
|
@filename = filename
|
@@ -29,32 +29,34 @@ end
|
|
29
29
|
|
30
30
|
|
31
31
|
class Engine < ::Rails::Engine
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
{
|
39
|
-
|
40
|
-
{
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
config.
|
52
|
-
|
53
|
-
|
54
|
-
|
32
|
+
if defined?(::Sprockets::Railtie)
|
33
|
+
require 'sprockets/version'
|
34
|
+
v2 = Gem::Dependency.new('', ' ~> 2')
|
35
|
+
vgte3 = Gem::Dependency.new('', ' >= 3')
|
36
|
+
sprockets_version = Gem::Version.new(::Sprockets::VERSION).release
|
37
|
+
initializer_args = case sprockets_version
|
38
|
+
when -> (v) { v2.match?('', v) }
|
39
|
+
{ after: "sprockets.environment" }
|
40
|
+
when -> (v) { vgte3.match?('', v) }
|
41
|
+
{ after: :engines_blank_point, before: :finisher_hook }
|
42
|
+
else
|
43
|
+
raise StandardError, "Sprockets version #{sprockets_version} is not supported"
|
44
|
+
end
|
45
|
+
|
46
|
+
initializer 'js-routes.dependent_on_routes', initializer_args do
|
47
|
+
case sprockets_version
|
48
|
+
when -> (v) { v2.match?('', v) },
|
49
|
+
-> (v) { vgte3.match?('', v) }
|
50
|
+
|
51
|
+
Rails.application.config.assets.configure do |config|
|
52
|
+
config.register_preprocessor(
|
53
|
+
"application/javascript",
|
54
|
+
SprocketsExtension,
|
55
|
+
)
|
56
|
+
end
|
57
|
+
else
|
58
|
+
raise StandardError, "Sprockets version #{sprockets_version} is not supported"
|
55
59
|
end
|
56
|
-
else
|
57
|
-
raise StandardError, "Sprockets version #{sprockets_version} is not supported"
|
58
60
|
end
|
59
61
|
end
|
60
62
|
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
require "js_routes/configuration"
|
2
|
+
require "js_routes/route"
|
3
|
+
|
4
|
+
module JsRoutes
|
5
|
+
class Instance # :nodoc:
|
6
|
+
|
7
|
+
attr_reader :configuration
|
8
|
+
#
|
9
|
+
# Implementation
|
10
|
+
#
|
11
|
+
|
12
|
+
def initialize(options = {})
|
13
|
+
@configuration = JsRoutes.configuration.merge(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def generate
|
17
|
+
# Ensure routes are loaded. If they're not, load them.
|
18
|
+
if named_routes.empty? && application.respond_to?(:reload_routes!)
|
19
|
+
application.reload_routes!
|
20
|
+
end
|
21
|
+
content = File.read(@configuration.source_file)
|
22
|
+
|
23
|
+
if !@configuration.dts?
|
24
|
+
content = js_variables.inject(content) do |js, (key, value)|
|
25
|
+
js.gsub!("RubyVariables.#{key}", value.to_s) ||
|
26
|
+
raise("Missing key #{key} in JS template")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
content + routes_export + prevent_types_export
|
30
|
+
end
|
31
|
+
|
32
|
+
def generate!
|
33
|
+
# Some libraries like Devise did not load their routes yet
|
34
|
+
# so we will wait until initialization process finishes
|
35
|
+
# https://github.com/railsware/js-routes/issues/7
|
36
|
+
Rails.configuration.after_initialize do
|
37
|
+
file_path = Rails.root.join(@configuration.output_file)
|
38
|
+
source_code = generate
|
39
|
+
|
40
|
+
# We don't need to rewrite file if it already exist and have same content.
|
41
|
+
# It helps asset pipeline or webpack understand that file wasn't changed.
|
42
|
+
next if File.exist?(file_path) && File.read(file_path) == source_code
|
43
|
+
|
44
|
+
File.open(file_path, 'w') do |f|
|
45
|
+
f.write source_code
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def js_variables
|
53
|
+
{
|
54
|
+
'GEM_VERSION' => JsRoutes::VERSION,
|
55
|
+
'ROUTES_OBJECT' => routes_object,
|
56
|
+
'RAILS_VERSION' => ActionPack.version,
|
57
|
+
'DEPRECATED_GLOBBING_BEHAVIOR' => ActionPack::VERSION::MAJOR == 4 && ActionPack::VERSION::MINOR == 0,
|
58
|
+
|
59
|
+
'APP_CLASS' => application.class.to_s,
|
60
|
+
'DEFAULT_URL_OPTIONS' => json(@configuration.default_url_options),
|
61
|
+
'PREFIX' => json(@configuration.prefix),
|
62
|
+
'SPECIAL_OPTIONS_KEY' => json(@configuration.special_options_key),
|
63
|
+
'SERIALIZER' => @configuration.serializer || json(nil),
|
64
|
+
'MODULE_TYPE' => json(@configuration.module_type),
|
65
|
+
'WRAPPER' => wrapper_variable,
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
def wrapper_variable
|
70
|
+
case @configuration.module_type
|
71
|
+
when 'ESM'
|
72
|
+
'const __jsr = '
|
73
|
+
when 'NIL'
|
74
|
+
namespace = @configuration.namespace
|
75
|
+
if namespace
|
76
|
+
if namespace.include?('.')
|
77
|
+
"#{namespace} = "
|
78
|
+
else
|
79
|
+
"(typeof window !== 'undefined' ? window : this).#{namespace} = "
|
80
|
+
end
|
81
|
+
else
|
82
|
+
''
|
83
|
+
end
|
84
|
+
else
|
85
|
+
''
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def application
|
90
|
+
@configuration.application
|
91
|
+
end
|
92
|
+
|
93
|
+
def json(string)
|
94
|
+
JsRoutes.json(string)
|
95
|
+
end
|
96
|
+
|
97
|
+
def named_routes
|
98
|
+
application.routes.named_routes.to_a
|
99
|
+
end
|
100
|
+
|
101
|
+
def routes_object
|
102
|
+
return json({}) if @configuration.modern?
|
103
|
+
properties = routes_list.map do |comment, name, body|
|
104
|
+
"#{comment}#{name}: #{body}".indent(2)
|
105
|
+
end
|
106
|
+
"{\n" + properties.join(",\n\n") + "}\n"
|
107
|
+
end
|
108
|
+
|
109
|
+
def static_exports
|
110
|
+
[:configure, :config, :serialize].map do |name|
|
111
|
+
[
|
112
|
+
"", name,
|
113
|
+
@configuration.dts? ?
|
114
|
+
"RouterExposedMethods['#{name}']" :
|
115
|
+
"__jsr.#{name}"
|
116
|
+
]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def routes_export
|
121
|
+
return "" unless @configuration.modern?
|
122
|
+
[*static_exports, *routes_list].map do |comment, name, body|
|
123
|
+
"#{comment}export const #{name}#{export_separator}#{body};\n\n"
|
124
|
+
end.join
|
125
|
+
end
|
126
|
+
|
127
|
+
def prevent_types_export
|
128
|
+
return "" unless @configuration.dts?
|
129
|
+
<<-JS
|
130
|
+
// By some reason this line prevents all types in a file
|
131
|
+
// from being automatically exported
|
132
|
+
export {};
|
133
|
+
JS
|
134
|
+
end
|
135
|
+
|
136
|
+
def export_separator
|
137
|
+
@configuration.dts? ? ': ' : ' = '
|
138
|
+
end
|
139
|
+
|
140
|
+
def routes_list
|
141
|
+
named_routes.sort_by(&:first).flat_map do |_, route|
|
142
|
+
route_helpers_if_match(route) + mounted_app_routes(route)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def mounted_app_routes(route)
|
147
|
+
rails_engine_app = app_from_route(route)
|
148
|
+
if rails_engine_app.respond_to?(:superclass) &&
|
149
|
+
rails_engine_app.superclass == Rails::Engine && !route.path.anchored
|
150
|
+
rails_engine_app.routes.named_routes.flat_map do |_, engine_route|
|
151
|
+
route_helpers_if_match(engine_route, route)
|
152
|
+
end
|
153
|
+
else
|
154
|
+
[]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def app_from_route(route)
|
159
|
+
app = route.app
|
160
|
+
# rails engine in Rails 4.2 use additional
|
161
|
+
# ActionDispatch::Routing::Mapper::Constraints, which contain app
|
162
|
+
if app.respond_to?(:app) && app.respond_to?(:constraints)
|
163
|
+
app.app
|
164
|
+
else
|
165
|
+
app
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def route_helpers_if_match(route, parent_route = nil)
|
170
|
+
Route.new(@configuration, route, parent_route).helpers
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
data/lib/js_routes/middleware.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
module JsRoutes
|
2
2
|
# A Rack middleware that automatically updates routes file
|
3
3
|
# whenever routes.rb is modified
|
4
4
|
#
|
@@ -21,12 +21,16 @@ class JsRoutes
|
|
21
21
|
def update_js_routes
|
22
22
|
new_mtime = routes_mtime
|
23
23
|
unless new_mtime == @mtime
|
24
|
-
|
25
|
-
JsRoutes.definitions!
|
24
|
+
regenerate
|
26
25
|
@mtime = new_mtime
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
29
|
+
def regenerate
|
30
|
+
JsRoutes.generate!
|
31
|
+
JsRoutes.definitions!
|
32
|
+
end
|
33
|
+
|
30
34
|
def routes_mtime
|
31
35
|
File.mtime(@routes_file)
|
32
36
|
rescue Errno::ENOENT
|
data/lib/js_routes/route.rb
CHANGED
data/lib/js_routes/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "2.2.
|
1
|
+
module JsRoutes
|
2
|
+
VERSION = "2.2.4"
|
3
3
|
end
|