js-routes 2.1.1 → 2.2.2
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 +21 -0
- data/Readme.md +87 -49
- data/lib/js_routes/configuration.rb +111 -0
- data/lib/js_routes/engine.rb +1 -1
- data/lib/js_routes/generators/middleware.rb +58 -0
- data/lib/js_routes/generators/webpacker.rb +1 -1
- data/lib/js_routes/instance.rb +154 -0
- data/lib/js_routes/middleware.rb +36 -0
- data/lib/js_routes/route.rb +172 -0
- data/lib/js_routes/version.rb +2 -2
- data/lib/js_routes.rb +11 -421
- data/lib/routes.js +10 -7
- data/lib/routes.ts +13 -8
- 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 +8 -2
@@ -0,0 +1,172 @@
|
|
1
|
+
module JsRoutes
|
2
|
+
class Route #:nodoc:
|
3
|
+
FILTERED_DEFAULT_PARTS = [:controller, :action]
|
4
|
+
URL_OPTIONS = [:protocol, :domain, :host, :port, :subdomain]
|
5
|
+
NODE_TYPES = {
|
6
|
+
GROUP: 1,
|
7
|
+
CAT: 2,
|
8
|
+
SYMBOL: 3,
|
9
|
+
OR: 4,
|
10
|
+
STAR: 5,
|
11
|
+
LITERAL: 6,
|
12
|
+
SLASH: 7,
|
13
|
+
DOT: 8
|
14
|
+
}
|
15
|
+
|
16
|
+
attr_reader :configuration, :route, :parent_route
|
17
|
+
|
18
|
+
def initialize(configuration, route, parent_route = nil)
|
19
|
+
@configuration = configuration
|
20
|
+
@route = route
|
21
|
+
@parent_route = parent_route
|
22
|
+
end
|
23
|
+
|
24
|
+
def helpers
|
25
|
+
helper_types.map do |absolute|
|
26
|
+
[ documentation, helper_name(absolute), body(absolute) ]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def helper_types
|
31
|
+
return [] unless match_configuration?
|
32
|
+
@configuration[:url_links] ? [true, false] : [false]
|
33
|
+
end
|
34
|
+
|
35
|
+
def body(absolute)
|
36
|
+
@configuration.dts? ?
|
37
|
+
definition_body : "__jsr.r(#{arguments(absolute).map{|a| json(a)}.join(', ')})"
|
38
|
+
end
|
39
|
+
|
40
|
+
def definition_body
|
41
|
+
args = required_parts.map{|p| "#{apply_case(p)}: RequiredRouteParameter"}
|
42
|
+
args << "options?: #{optional_parts_type} & RouteOptions"
|
43
|
+
"((\n#{args.join(",\n").indent(2)}\n) => string) & RouteHelperExtras"
|
44
|
+
end
|
45
|
+
|
46
|
+
def optional_parts_type
|
47
|
+
@optional_parts_type ||=
|
48
|
+
"{" + optional_parts.map {|p| "#{p}?: OptionalRouteParameter"}.join(', ') + "}"
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
|
53
|
+
def arguments(absolute)
|
54
|
+
absolute ? [*base_arguments, true] : base_arguments
|
55
|
+
end
|
56
|
+
|
57
|
+
def match_configuration?
|
58
|
+
!match?(@configuration[:exclude]) && match?(@configuration[:include])
|
59
|
+
end
|
60
|
+
|
61
|
+
def base_name
|
62
|
+
@base_name ||= parent_route ?
|
63
|
+
[parent_route.name, route.name].join('_') : route.name
|
64
|
+
end
|
65
|
+
|
66
|
+
def parent_spec
|
67
|
+
parent_route&.path&.spec
|
68
|
+
end
|
69
|
+
|
70
|
+
def spec
|
71
|
+
route.path.spec
|
72
|
+
end
|
73
|
+
|
74
|
+
def json(value)
|
75
|
+
JsRoutes.json(value)
|
76
|
+
end
|
77
|
+
|
78
|
+
def helper_name(absolute)
|
79
|
+
suffix = absolute ? :url : @configuration[:compact] ? nil : :path
|
80
|
+
apply_case(base_name, suffix)
|
81
|
+
end
|
82
|
+
|
83
|
+
def documentation
|
84
|
+
return nil unless @configuration[:documentation]
|
85
|
+
<<-JS
|
86
|
+
/**
|
87
|
+
* Generates rails route to
|
88
|
+
* #{parent_spec}#{spec}#{documentation_params}
|
89
|
+
* @param {object | undefined} options
|
90
|
+
* @returns {string} route path
|
91
|
+
*/
|
92
|
+
JS
|
93
|
+
end
|
94
|
+
|
95
|
+
def required_parts
|
96
|
+
route.required_parts
|
97
|
+
end
|
98
|
+
|
99
|
+
def optional_parts
|
100
|
+
route.path.optional_names
|
101
|
+
end
|
102
|
+
|
103
|
+
def base_arguments
|
104
|
+
@base_arguments ||= [parts_table, serialize(spec, parent_spec)]
|
105
|
+
end
|
106
|
+
|
107
|
+
def parts_table
|
108
|
+
parts_table = {}
|
109
|
+
route.parts.each do |part, hash|
|
110
|
+
parts_table[part] ||= {}
|
111
|
+
if required_parts.include?(part)
|
112
|
+
# Using shortened keys to reduce js file size
|
113
|
+
parts_table[part][:r] = true
|
114
|
+
end
|
115
|
+
end
|
116
|
+
route.defaults.each do |part, value|
|
117
|
+
if FILTERED_DEFAULT_PARTS.exclude?(part) &&
|
118
|
+
URL_OPTIONS.include?(part) || parts_table[part]
|
119
|
+
parts_table[part] ||= {}
|
120
|
+
# Using shortened keys to reduce js file size
|
121
|
+
parts_table[part][:d] = value
|
122
|
+
end
|
123
|
+
end
|
124
|
+
parts_table
|
125
|
+
end
|
126
|
+
|
127
|
+
def documentation_params
|
128
|
+
required_parts.map do |param|
|
129
|
+
"\n * @param {any} #{apply_case(param)}"
|
130
|
+
end.join
|
131
|
+
end
|
132
|
+
|
133
|
+
def match?(matchers)
|
134
|
+
Array(matchers).any? { |regex| base_name =~ regex }
|
135
|
+
end
|
136
|
+
|
137
|
+
def apply_case(*values)
|
138
|
+
value = values.compact.map(&:to_s).join('_')
|
139
|
+
@configuration[:camel_case] ? value.camelize(:lower) : value
|
140
|
+
end
|
141
|
+
|
142
|
+
# This function serializes Journey route into JSON structure
|
143
|
+
# We do not use Hash for human readable serialization
|
144
|
+
# And preffer Array serialization because it is shorter.
|
145
|
+
# Routes.js file will be smaller.
|
146
|
+
def serialize(spec, parent_spec=nil)
|
147
|
+
return nil unless spec
|
148
|
+
# Rails 4 globbing requires * removal
|
149
|
+
return spec.tr(':*', '') if spec.is_a?(String)
|
150
|
+
|
151
|
+
result = serialize_spec(spec, parent_spec)
|
152
|
+
if parent_spec && result[1].is_a?(String) && parent_spec.type != :SLASH
|
153
|
+
result = [
|
154
|
+
# We encode node symbols as integer
|
155
|
+
# to reduce the routes.js file size
|
156
|
+
NODE_TYPES[:CAT],
|
157
|
+
serialize_spec(parent_spec),
|
158
|
+
result
|
159
|
+
]
|
160
|
+
end
|
161
|
+
result
|
162
|
+
end
|
163
|
+
|
164
|
+
def serialize_spec(spec, parent_spec = nil)
|
165
|
+
[
|
166
|
+
NODE_TYPES[spec.type],
|
167
|
+
serialize(spec.left, parent_spec),
|
168
|
+
spec.respond_to?(:right) ? serialize(spec.right) : nil
|
169
|
+
].compact
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
data/lib/js_routes/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "2.
|
1
|
+
module JsRoutes
|
2
|
+
VERSION = "2.2.2"
|
3
3
|
end
|
data/lib/js_routes.rb
CHANGED
@@ -1,109 +1,12 @@
|
|
1
|
-
require 'uri'
|
2
1
|
if defined?(::Rails) && defined?(::Sprockets::Railtie)
|
3
2
|
require 'js_routes/engine'
|
4
3
|
end
|
5
4
|
require 'js_routes/version'
|
5
|
+
require "js_routes/configuration"
|
6
|
+
require "js_routes/instance"
|
6
7
|
require 'active_support/core_ext/string/indent'
|
7
8
|
|
8
|
-
|
9
|
-
|
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)
|
29
|
-
|
30
|
-
def initialize(attributes = nil)
|
31
|
-
assign(DEFAULTS)
|
32
|
-
return unless attributes
|
33
|
-
assign(attributes)
|
34
|
-
end
|
35
|
-
|
36
|
-
def assign(attributes)
|
37
|
-
attributes.each do |attribute, value|
|
38
|
-
value = value.call if value.is_a?(Proc)
|
39
|
-
send(:"#{attribute}=", value)
|
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 = Rails.root.join('app', 'javascript')
|
79
|
-
sprockets_dir = Rails.root.join('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
|
-
def normalize_and_verify
|
87
|
-
normalize
|
88
|
-
verify
|
89
|
-
end
|
90
|
-
|
91
|
-
protected
|
92
|
-
|
93
|
-
def default_file_name
|
94
|
-
dts? ? "routes.d.ts" : "routes.js"
|
95
|
-
end
|
96
|
-
|
97
|
-
def normalize
|
98
|
-
self.module_type = module_type&.upcase || 'NIL'
|
99
|
-
end
|
100
|
-
|
101
|
-
def verify
|
102
|
-
if module_type != 'NIL' && namespace
|
103
|
-
raise "JsRoutes namespace option can only be used if module_type is nil"
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
9
|
+
module JsRoutes
|
107
10
|
|
108
11
|
#
|
109
12
|
# API
|
@@ -111,8 +14,7 @@ class JsRoutes
|
|
111
14
|
|
112
15
|
class << self
|
113
16
|
def setup(&block)
|
114
|
-
configuration.
|
115
|
-
configuration.normalize_and_verify
|
17
|
+
configuration.assign(&block)
|
116
18
|
end
|
117
19
|
|
118
20
|
def configuration
|
@@ -120,11 +22,11 @@ class JsRoutes
|
|
120
22
|
end
|
121
23
|
|
122
24
|
def generate(**opts)
|
123
|
-
new(opts).generate
|
25
|
+
Instance.new(opts).generate
|
124
26
|
end
|
125
27
|
|
126
|
-
def generate!(file_name=
|
127
|
-
new(file: file_name, **opts).generate!
|
28
|
+
def generate!(file_name = configuration.file, **opts)
|
29
|
+
Instance.new(file: file_name, **opts).generate!
|
128
30
|
end
|
129
31
|
|
130
32
|
def definitions(**opts)
|
@@ -132,7 +34,7 @@ class JsRoutes
|
|
132
34
|
end
|
133
35
|
|
134
36
|
def definitions!(file_name = nil, **opts)
|
135
|
-
file_name ||= configuration.file&.sub
|
37
|
+
file_name ||= configuration.file&.sub(%r{(\.d)?\.(j|t)s\Z}, ".d.ts")
|
136
38
|
generate!(file_name, module_type: 'DTS', **opts)
|
137
39
|
end
|
138
40
|
|
@@ -140,322 +42,10 @@ class JsRoutes
|
|
140
42
|
ActiveSupport::JSON.encode(string)
|
141
43
|
end
|
142
44
|
end
|
143
|
-
|
144
|
-
#
|
145
|
-
# Implementation
|
146
|
-
#
|
147
|
-
|
148
|
-
def initialize(options = {})
|
149
|
-
@configuration = self.class.configuration.merge(options)
|
150
|
-
end
|
151
|
-
|
152
|
-
def generate
|
153
|
-
# Ensure routes are loaded. If they're not, load them.
|
154
|
-
if named_routes.to_a.empty? && application.respond_to?(:reload_routes!)
|
155
|
-
application.reload_routes!
|
156
|
-
end
|
157
|
-
content = File.read(@configuration.source_file)
|
158
|
-
|
159
|
-
if !@configuration.dts?
|
160
|
-
content = js_variables.inject(content) do |js, (key, value)|
|
161
|
-
js.gsub!("RubyVariables.#{key}", value.to_s) ||
|
162
|
-
raise("Missing key #{key} in JS template")
|
163
|
-
end
|
164
|
-
end
|
165
|
-
content + routes_export + prevent_types_export
|
166
|
-
end
|
167
|
-
|
168
|
-
def generate!
|
169
|
-
# Some libraries like Devise did not load their routes yet
|
170
|
-
# so we will wait until initialization process finishes
|
171
|
-
# https://github.com/railsware/js-routes/issues/7
|
172
|
-
Rails.configuration.after_initialize do
|
173
|
-
file_path = Rails.root.join(@configuration.output_file)
|
174
|
-
source_code = generate
|
175
|
-
|
176
|
-
# We don't need to rewrite file if it already exist and have same content.
|
177
|
-
# It helps asset pipeline or webpack understand that file wasn't changed.
|
178
|
-
next if File.exist?(file_path) && File.read(file_path) == source_code
|
179
|
-
|
180
|
-
File.open(file_path, 'w') do |f|
|
181
|
-
f.write source_code
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
protected
|
187
|
-
|
188
|
-
def js_variables
|
189
|
-
{
|
190
|
-
'GEM_VERSION' => JsRoutes::VERSION,
|
191
|
-
'ROUTES_OBJECT' => routes_object,
|
192
|
-
'RAILS_VERSION' => ActionPack.version,
|
193
|
-
'DEPRECATED_GLOBBING_BEHAVIOR' => ActionPack::VERSION::MAJOR == 4 && ActionPack::VERSION::MINOR == 0,
|
194
|
-
|
195
|
-
'APP_CLASS' => application.class.to_s,
|
196
|
-
'NAMESPACE' => json(@configuration.namespace),
|
197
|
-
'DEFAULT_URL_OPTIONS' => json(@configuration.default_url_options),
|
198
|
-
'PREFIX' => json(@configuration.prefix),
|
199
|
-
'SPECIAL_OPTIONS_KEY' => json(@configuration.special_options_key),
|
200
|
-
'SERIALIZER' => @configuration.serializer || json(nil),
|
201
|
-
'MODULE_TYPE' => json(@configuration.module_type),
|
202
|
-
'WRAPPER' => @configuration.esm? ? 'const __jsr = ' : '',
|
203
|
-
}
|
204
|
-
end
|
205
|
-
|
206
|
-
def application
|
207
|
-
@configuration.application
|
208
|
-
end
|
209
|
-
|
210
|
-
def json(string)
|
211
|
-
self.class.json(string)
|
212
|
-
end
|
213
|
-
|
214
|
-
def named_routes
|
215
|
-
application.routes.named_routes.to_a
|
216
|
-
end
|
217
|
-
|
218
|
-
def routes_object
|
219
|
-
return json({}) if @configuration.modern?
|
220
|
-
properties = routes_list.map do |comment, name, body|
|
221
|
-
"#{comment}#{name}: #{body}".indent(2)
|
222
|
-
end
|
223
|
-
"{\n" + properties.join(",\n\n") + "}\n"
|
224
|
-
end
|
225
|
-
|
226
|
-
def static_exports
|
227
|
-
[:configure, :config, :serialize].map do |name|
|
228
|
-
[
|
229
|
-
"", name,
|
230
|
-
@configuration.dts? ?
|
231
|
-
"RouterExposedMethods['#{name}']" :
|
232
|
-
"__jsr.#{name}"
|
233
|
-
]
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
def routes_export
|
238
|
-
return "" unless @configuration.modern?
|
239
|
-
[*static_exports, *routes_list].map do |comment, name, body|
|
240
|
-
"#{comment}export const #{name}#{export_separator}#{body};\n\n"
|
241
|
-
end.join
|
242
|
-
end
|
243
|
-
|
244
|
-
def prevent_types_export
|
245
|
-
return "" unless @configuration.dts?
|
246
|
-
<<-JS
|
247
|
-
// By some reason this line prevents all types in a file
|
248
|
-
// from being automatically exported
|
249
|
-
export {};
|
250
|
-
JS
|
251
|
-
end
|
252
|
-
|
253
|
-
def export_separator
|
254
|
-
@configuration.dts? ? ': ' : ' = '
|
255
|
-
end
|
256
|
-
|
257
|
-
def routes_list
|
258
|
-
named_routes.sort_by(&:first).flat_map do |_, route|
|
259
|
-
route_helpers_if_match(route) + mounted_app_routes(route)
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
def mounted_app_routes(route)
|
264
|
-
rails_engine_app = app_from_route(route)
|
265
|
-
if rails_engine_app.respond_to?(:superclass) &&
|
266
|
-
rails_engine_app.superclass == Rails::Engine && !route.path.anchored
|
267
|
-
rails_engine_app.routes.named_routes.flat_map do |_, engine_route|
|
268
|
-
route_helpers_if_match(engine_route, route)
|
269
|
-
end
|
270
|
-
else
|
271
|
-
[]
|
272
|
-
end
|
273
|
-
end
|
274
|
-
|
275
|
-
def app_from_route(route)
|
276
|
-
# rails engine in Rails 4.2 use additional
|
277
|
-
# ActionDispatch::Routing::Mapper::Constraints, which contain app
|
278
|
-
if route.app.respond_to?(:app) && route.app.respond_to?(:constraints)
|
279
|
-
route.app.app
|
280
|
-
else
|
281
|
-
route.app
|
282
|
-
end
|
283
|
-
end
|
284
|
-
|
285
|
-
def route_helpers_if_match(route, parent_route = nil)
|
286
|
-
JsRoute.new(@configuration, route, parent_route).helpers
|
287
|
-
end
|
288
|
-
|
289
|
-
class JsRoute #:nodoc:
|
290
|
-
FILTERED_DEFAULT_PARTS = [:controller, :action]
|
291
|
-
URL_OPTIONS = [:protocol, :domain, :host, :port, :subdomain]
|
292
|
-
NODE_TYPES = {
|
293
|
-
GROUP: 1,
|
294
|
-
CAT: 2,
|
295
|
-
SYMBOL: 3,
|
296
|
-
OR: 4,
|
297
|
-
STAR: 5,
|
298
|
-
LITERAL: 6,
|
299
|
-
SLASH: 7,
|
300
|
-
DOT: 8
|
301
|
-
}
|
302
|
-
|
303
|
-
attr_reader :configuration, :route, :parent_route
|
304
|
-
|
305
|
-
def initialize(configuration, route, parent_route = nil)
|
306
|
-
@configuration = configuration
|
307
|
-
@route = route
|
308
|
-
@parent_route = parent_route
|
309
|
-
end
|
310
|
-
|
311
|
-
def helpers
|
312
|
-
helper_types.map do |absolute|
|
313
|
-
[ documentation, helper_name(absolute), body(absolute) ]
|
314
|
-
end
|
315
|
-
end
|
316
|
-
|
317
|
-
def helper_types
|
318
|
-
return [] unless match_configuration?
|
319
|
-
@configuration[:url_links] ? [true, false] : [false]
|
320
|
-
end
|
321
|
-
|
322
|
-
def body(absolute)
|
323
|
-
@configuration.dts? ?
|
324
|
-
definition_body : "__jsr.r(#{arguments(absolute).map{|a| json(a)}.join(', ')})"
|
325
|
-
end
|
326
|
-
|
327
|
-
def definition_body
|
328
|
-
args = required_parts.map{|p| "#{apply_case(p)}: RequiredRouteParameter"}
|
329
|
-
args << "options?: #{optional_parts_type} & RouteOptions"
|
330
|
-
"((\n#{args.join(",\n").indent(2)}\n) => string) & RouteHelperExtras"
|
331
|
-
end
|
332
|
-
|
333
|
-
def optional_parts_type
|
334
|
-
@optional_parts_type ||=
|
335
|
-
"{" + optional_parts.map {|p| "#{p}?: OptionalRouteParameter"}.join(', ') + "}"
|
336
|
-
end
|
337
|
-
|
338
|
-
protected
|
339
|
-
|
340
|
-
def arguments(absolute)
|
341
|
-
absolute ? [*base_arguments, true] : base_arguments
|
342
|
-
end
|
343
|
-
|
344
|
-
def match_configuration?
|
345
|
-
!match?(@configuration[:exclude]) && match?(@configuration[:include])
|
346
|
-
end
|
347
|
-
|
348
|
-
def base_name
|
349
|
-
@base_name ||= parent_route ?
|
350
|
-
[parent_route.name, route.name].join('_') : route.name
|
351
|
-
end
|
352
|
-
|
353
|
-
def parent_spec
|
354
|
-
parent_route&.path&.spec
|
355
|
-
end
|
356
|
-
|
357
|
-
def spec
|
358
|
-
route.path.spec
|
359
|
-
end
|
360
|
-
|
361
|
-
def json(value)
|
362
|
-
JsRoutes.json(value)
|
363
|
-
end
|
364
|
-
|
365
|
-
def helper_name(absolute)
|
366
|
-
suffix = absolute ? :url : @configuration[:compact] ? nil : :path
|
367
|
-
apply_case(base_name, suffix)
|
368
|
-
end
|
369
|
-
|
370
|
-
def documentation
|
371
|
-
return nil unless @configuration[:documentation]
|
372
|
-
<<-JS
|
373
|
-
/**
|
374
|
-
* Generates rails route to
|
375
|
-
* #{parent_spec}#{spec}#{documentation_params}
|
376
|
-
* @param {object | undefined} options
|
377
|
-
* @returns {string} route path
|
378
|
-
*/
|
379
|
-
JS
|
380
|
-
end
|
381
|
-
|
382
|
-
def required_parts
|
383
|
-
route.required_parts
|
384
|
-
end
|
385
|
-
|
386
|
-
def optional_parts
|
387
|
-
route.path.optional_names
|
388
|
-
end
|
389
|
-
|
390
|
-
def base_arguments
|
391
|
-
@base_arguments ||= [parts_table, serialize(spec, parent_spec)]
|
392
|
-
end
|
393
|
-
|
394
|
-
def parts_table
|
395
|
-
parts_table = {}
|
396
|
-
route.parts.each do |part, hash|
|
397
|
-
parts_table[part] ||= {}
|
398
|
-
if required_parts.include?(part)
|
399
|
-
# Using shortened keys to reduce js file size
|
400
|
-
parts_table[part][:r] = true
|
401
|
-
end
|
402
|
-
end
|
403
|
-
route.defaults.each do |part, value|
|
404
|
-
if FILTERED_DEFAULT_PARTS.exclude?(part) &&
|
405
|
-
URL_OPTIONS.include?(part) || parts_table[part]
|
406
|
-
parts_table[part] ||= {}
|
407
|
-
# Using shortened keys to reduce js file size
|
408
|
-
parts_table[part][:d] = value
|
409
|
-
end
|
410
|
-
end
|
411
|
-
parts_table
|
412
|
-
end
|
413
|
-
|
414
|
-
def documentation_params
|
415
|
-
required_parts.map do |param|
|
416
|
-
"\n * @param {any} #{apply_case(param)}"
|
417
|
-
end.join
|
418
|
-
end
|
419
|
-
|
420
|
-
def match?(matchers)
|
421
|
-
Array(matchers).any? { |regex| base_name =~ regex }
|
422
|
-
end
|
423
|
-
|
424
|
-
def apply_case(*values)
|
425
|
-
value = values.compact.map(&:to_s).join('_')
|
426
|
-
@configuration[:camel_case] ? value.camelize(:lower) : value
|
427
|
-
end
|
428
|
-
|
429
|
-
# This function serializes Journey route into JSON structure
|
430
|
-
# We do not use Hash for human readable serialization
|
431
|
-
# And preffer Array serialization because it is shorter.
|
432
|
-
# Routes.js file will be smaller.
|
433
|
-
def serialize(spec, parent_spec=nil)
|
434
|
-
return nil unless spec
|
435
|
-
# Rails 4 globbing requires * removal
|
436
|
-
return spec.tr(':*', '') if spec.is_a?(String)
|
437
|
-
|
438
|
-
result = serialize_spec(spec, parent_spec)
|
439
|
-
if parent_spec && result[1].is_a?(String) && parent_spec.type != :SLASH
|
440
|
-
result = [
|
441
|
-
# We encode node symbols as integer
|
442
|
-
# to reduce the routes.js file size
|
443
|
-
NODE_TYPES[:CAT],
|
444
|
-
serialize_spec(parent_spec),
|
445
|
-
result
|
446
|
-
]
|
447
|
-
end
|
448
|
-
result
|
449
|
-
end
|
450
|
-
|
451
|
-
def serialize_spec(spec, parent_spec = nil)
|
452
|
-
[
|
453
|
-
NODE_TYPES[spec.type],
|
454
|
-
serialize(spec.left, parent_spec),
|
455
|
-
spec.respond_to?(:right) ? serialize(spec.right) : nil
|
456
|
-
].compact
|
457
|
-
end
|
45
|
+
module Generators
|
458
46
|
end
|
459
47
|
end
|
460
48
|
|
49
|
+
require "js_routes/middleware"
|
461
50
|
require "js_routes/generators/webpacker"
|
51
|
+
require "js_routes/generators/middleware"
|
data/lib/routes.js
CHANGED
@@ -16,6 +16,7 @@ RubyVariables.WRAPPER((that) => {
|
|
16
16
|
NodeTypes[NodeTypes["DOT"] = 8] = "DOT";
|
17
17
|
})(NodeTypes || (NodeTypes = {}));
|
18
18
|
const Root = that;
|
19
|
+
const isBroswer = typeof window !== "undefined";
|
19
20
|
const ModuleReferences = {
|
20
21
|
CJS: {
|
21
22
|
define(routes) {
|
@@ -73,7 +74,7 @@ RubyVariables.WRAPPER((that) => {
|
|
73
74
|
Utils.namespace(Root, RubyVariables.NAMESPACE, routes);
|
74
75
|
},
|
75
76
|
isSupported() {
|
76
|
-
return !!Root;
|
77
|
+
return !RubyVariables.NAMESPACE || !!Root;
|
77
78
|
},
|
78
79
|
},
|
79
80
|
DTS: {
|
@@ -204,7 +205,9 @@ RubyVariables.WRAPPER((that) => {
|
|
204
205
|
throw new Error("Too many parameters provided for path");
|
205
206
|
}
|
206
207
|
let use_all_parts = args.length > required_params.length;
|
207
|
-
const parts_options = {
|
208
|
+
const parts_options = {
|
209
|
+
...this.configuration.default_url_options,
|
210
|
+
};
|
208
211
|
for (const key in options) {
|
209
212
|
const value = options[key];
|
210
213
|
if (!hasProp(options, key))
|
@@ -419,15 +422,15 @@ RubyVariables.WRAPPER((that) => {
|
|
419
422
|
}
|
420
423
|
current_host() {
|
421
424
|
var _a;
|
422
|
-
return ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.hostname) || "";
|
425
|
+
return (isBroswer && ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.hostname)) || "";
|
423
426
|
}
|
424
427
|
current_protocol() {
|
425
428
|
var _a, _b;
|
426
|
-
return ((_b = (_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.protocol) === null || _b === void 0 ? void 0 : _b.replace(/:$/, "")) || "http";
|
429
|
+
return ((isBroswer && ((_b = (_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.protocol) === null || _b === void 0 ? void 0 : _b.replace(/:$/, ""))) || "http");
|
427
430
|
}
|
428
431
|
current_port() {
|
429
432
|
var _a;
|
430
|
-
return ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.port) || "";
|
433
|
+
return (isBroswer && ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.port)) || "";
|
431
434
|
}
|
432
435
|
is_object(value) {
|
433
436
|
return (typeof value === "object" &&
|
@@ -445,7 +448,7 @@ RubyVariables.WRAPPER((that) => {
|
|
445
448
|
namespace(object, namespace, routes) {
|
446
449
|
const parts = (namespace === null || namespace === void 0 ? void 0 : namespace.split(".")) || [];
|
447
450
|
if (parts.length === 0) {
|
448
|
-
return
|
451
|
+
return;
|
449
452
|
}
|
450
453
|
for (let index = 0; index < parts.length; index++) {
|
451
454
|
const part = parts[index];
|
@@ -453,7 +456,7 @@ RubyVariables.WRAPPER((that) => {
|
|
453
456
|
object = object[part] || (object[part] = {});
|
454
457
|
}
|
455
458
|
else {
|
456
|
-
|
459
|
+
object[part] = routes;
|
457
460
|
}
|
458
461
|
}
|
459
462
|
}
|