js-routes 1.4.1 → 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 +5 -5
- data/.eslintrc.js +15 -0
- data/.gitignore +5 -0
- data/.nvmrc +1 -0
- data/.travis.yml +37 -30
- data/Appraisals +16 -13
- data/CHANGELOG.md +95 -0
- data/Rakefile +6 -2
- data/Readme.md +220 -88
- data/VERSION_2_UPGRADE.md +66 -0
- data/app/assets/javascripts/js-routes.js.erb +1 -1
- data/gemfiles/{rails40.gemfile → rails40_sprockets_2.gemfile} +1 -1
- data/gemfiles/{rails40_sprockets3.gemfile → rails40_sprockets_3.gemfile} +0 -0
- data/gemfiles/{rails41.gemfile → rails41_sprockets_2.gemfile} +1 -1
- data/gemfiles/{rails41_sprockets3.gemfile → rails41_sprockets_3.gemfile} +0 -0
- data/gemfiles/{rails32.gemfile → rails42_sprockets_2.gemfile} +2 -2
- data/gemfiles/{rails42_sprockets3.gemfile → rails42_sprockets_3.gemfile} +1 -1
- data/gemfiles/{rails50_sprockets3.gemfile → rails50_sprockets_3.gemfile} +1 -1
- data/gemfiles/rails51_sprockets_3.gemfile +8 -0
- data/gemfiles/rails52_sprockets_3.gemfile +8 -0
- data/js-routes.gemspec +9 -6
- data/lib/js_routes/engine.rb +6 -18
- data/lib/js_routes/version.rb +1 -1
- data/lib/js_routes.rb +329 -171
- data/lib/routes.d.ts +79 -0
- data/lib/routes.js +499 -485
- data/lib/routes.ts +732 -0
- data/lib/tasks/js_routes.rake +8 -2
- data/package.json +37 -0
- data/spec/dummy/app/assets/config/manifest.js +2 -0
- data/spec/js_routes/default_serializer_spec.rb +19 -3
- data/spec/js_routes/{amd_compatibility_spec.rb → module_types/amd_spec.rb} +1 -9
- data/spec/js_routes/module_types/cjs_spec.rb +15 -0
- 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/module_types/esm_spec.rb +45 -0
- data/spec/js_routes/{generated_javascript_spec.rb → module_types/umd_spec.rb} +33 -27
- data/spec/js_routes/options_spec.rb +92 -50
- data/spec/js_routes/rails_routes_compatibility_spec.rb +107 -45
- data/spec/js_routes/zzz_last_post_rails_init_spec.rb +19 -8
- data/spec/spec_helper.rb +45 -42
- data/spec/support/routes.rb +19 -14
- data/spec/tsconfig.json +4 -0
- data/tsconfig.json +28 -0
- data/yarn.lock +2145 -0
- metadata +47 -34
- data/gemfiles/rails42.gemfile +0 -8
- data/gemfiles/rails50.gemfile +0 -8
- data/lib/routes.js.coffee +0 -386
data/lib/js_routes.rb
CHANGED
@@ -1,46 +1,32 @@
|
|
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'
|
6
|
+
require 'active_support/core_ext/string/indent'
|
4
7
|
|
5
8
|
class JsRoutes
|
6
9
|
|
7
|
-
|
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)
|
10
29
|
|
11
|
-
DEFAULT_PATH = File.join('app','assets','javascripts','routes.js')
|
12
|
-
|
13
|
-
DEFAULTS = {
|
14
|
-
namespace: "Routes",
|
15
|
-
exclude: [],
|
16
|
-
include: //,
|
17
|
-
file: DEFAULT_PATH,
|
18
|
-
prefix: -> { Rails.application.config.relative_url_root || "" },
|
19
|
-
url_links: false,
|
20
|
-
camel_case: false,
|
21
|
-
default_url_options: {},
|
22
|
-
compact: false,
|
23
|
-
serializer: nil,
|
24
|
-
special_options_key: "_options",
|
25
|
-
application: -> { Rails.application }
|
26
|
-
}
|
27
|
-
|
28
|
-
NODE_TYPES = {
|
29
|
-
GROUP: 1,
|
30
|
-
CAT: 2,
|
31
|
-
SYMBOL: 3,
|
32
|
-
OR: 4,
|
33
|
-
STAR: 5,
|
34
|
-
LITERAL: 6,
|
35
|
-
SLASH: 7,
|
36
|
-
DOT: 8
|
37
|
-
}
|
38
|
-
|
39
|
-
LAST_OPTIONS_KEY = "options".freeze
|
40
|
-
FILTERED_DEFAULT_PARTS = [:controller, :action, :subdomain]
|
41
|
-
URL_OPTIONS = [:protocol, :domain, :host, :port, :subdomain]
|
42
|
-
|
43
|
-
class Configuration < Struct.new(*DEFAULTS.keys)
|
44
30
|
def initialize(attributes = nil)
|
45
31
|
assign(DEFAULTS)
|
46
32
|
return unless attributes
|
@@ -52,6 +38,7 @@ class JsRoutes
|
|
52
38
|
value = value.call if value.is_a?(Proc)
|
53
39
|
send(:"#{attribute}=", value)
|
54
40
|
end
|
41
|
+
normalize_and_verify
|
55
42
|
self
|
56
43
|
end
|
57
44
|
|
@@ -66,6 +53,52 @@ class JsRoutes
|
|
66
53
|
def to_hash
|
67
54
|
Hash[*members.zip(values).flatten(1)].symbolize_keys
|
68
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 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
|
101
|
+
end
|
69
102
|
end
|
70
103
|
|
71
104
|
#
|
@@ -75,11 +108,7 @@ class JsRoutes
|
|
75
108
|
class << self
|
76
109
|
def setup(&block)
|
77
110
|
configuration.tap(&block) if block
|
78
|
-
|
79
|
-
|
80
|
-
def options
|
81
|
-
ActiveSupport::Deprecation.warn('JsRoutes.options method is deprecated use JsRoutes.configuration instead')
|
82
|
-
configuration
|
111
|
+
configuration.normalize_and_verify
|
83
112
|
end
|
84
113
|
|
85
114
|
def configuration
|
@@ -90,22 +119,13 @@ class JsRoutes
|
|
90
119
|
new(opts).generate
|
91
120
|
end
|
92
121
|
|
93
|
-
def generate!(file_name=nil, opts
|
94
|
-
|
95
|
-
opts = file_name
|
96
|
-
file_name = opts[:file]
|
97
|
-
end
|
98
|
-
new(opts).generate!(file_name)
|
122
|
+
def generate!(file_name=nil, **opts)
|
123
|
+
new(file: file_name, **opts).generate!
|
99
124
|
end
|
100
125
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
def assert_usable_configuration!
|
105
|
-
if 3 == Rails::VERSION::MAJOR && !Rails.application.config.assets.initialize_on_precompile
|
106
|
-
raise("Cannot precompile js-routes unless environment is initialized. Please set config.assets.initialize_on_precompile to true.")
|
107
|
-
end
|
108
|
-
true
|
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!
|
109
129
|
end
|
110
130
|
|
111
131
|
def json(string)
|
@@ -126,66 +146,127 @@ class JsRoutes
|
|
126
146
|
if named_routes.to_a.empty? && application.respond_to?(:reload_routes!)
|
127
147
|
application.reload_routes!
|
128
148
|
end
|
149
|
+
content = File.read(@configuration.source_file)
|
129
150
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
"APP_CLASS" => application.class.to_s,
|
137
|
-
"NAMESPACE" => json(@configuration.namespace),
|
138
|
-
"DEFAULT_URL_OPTIONS" => json(@configuration.default_url_options),
|
139
|
-
"PREFIX" => json(@configuration.prefix),
|
140
|
-
"SPECIAL_OPTIONS_KEY" => json(@configuration.special_options_key),
|
141
|
-
"SERIALIZER" => @configuration.serializer || json(nil),
|
142
|
-
}.inject(File.read(File.dirname(__FILE__) + "/routes.js")) do |js, (key, value)|
|
143
|
-
js.gsub!(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) ||
|
154
|
+
raise("Missing key #{key} in JS template")
|
155
|
+
end
|
144
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
|
-
|
165
|
+
file_path = Rails.root.join(@configuration.output_file)
|
166
|
+
source_code = generate
|
167
|
+
|
168
|
+
# We don't need to rewrite file if it already exist and have same content.
|
169
|
+
# It helps asset pipeline or webpack understand that file wasn't changed.
|
170
|
+
next if File.exist?(file_path) && File.read(file_path) == source_code
|
171
|
+
|
172
|
+
File.open(file_path, 'w') do |f|
|
173
|
+
f.write source_code
|
155
174
|
end
|
156
175
|
end
|
157
176
|
end
|
158
177
|
|
159
178
|
protected
|
160
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
|
+
|
161
198
|
def application
|
162
199
|
@configuration.application
|
163
200
|
end
|
164
201
|
|
202
|
+
def json(string)
|
203
|
+
self.class.json(string)
|
204
|
+
end
|
205
|
+
|
165
206
|
def named_routes
|
166
207
|
application.routes.named_routes.to_a
|
167
208
|
end
|
168
209
|
|
169
|
-
def
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
210
|
+
def routes_object
|
211
|
+
return json({}) if @configuration.modern?
|
212
|
+
properties = routes_list.map do |comment, name, body|
|
213
|
+
"#{comment}#{name}: #{body}".indent(2)
|
214
|
+
end
|
215
|
+
"{\n" + properties.join(",\n\n") + "}\n"
|
216
|
+
end
|
217
|
+
|
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
|
227
|
+
end
|
228
|
+
|
229
|
+
def routes_export
|
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? ? ': ' : ' = '
|
247
|
+
end
|
248
|
+
|
249
|
+
def routes_list
|
250
|
+
named_routes.sort_by(&:first).flat_map do |_, route|
|
251
|
+
route_helpers_if_match(route) + mounted_app_routes(route)
|
252
|
+
end
|
174
253
|
end
|
175
254
|
|
176
255
|
def mounted_app_routes(route)
|
177
|
-
rails_engine_app =
|
178
|
-
if rails_engine_app.respond_to?(:superclass) &&
|
179
|
-
|
180
|
-
|
256
|
+
rails_engine_app = app_from_route(route)
|
257
|
+
if rails_engine_app.respond_to?(:superclass) &&
|
258
|
+
rails_engine_app.superclass == Rails::Engine && !route.path.anchored
|
259
|
+
rails_engine_app.routes.named_routes.flat_map do |_, engine_route|
|
260
|
+
route_helpers_if_match(engine_route, route)
|
181
261
|
end
|
182
262
|
else
|
183
263
|
[]
|
184
264
|
end
|
185
265
|
end
|
186
266
|
|
187
|
-
def
|
188
|
-
# rails engine in Rails 4.2 use additional
|
267
|
+
def app_from_route(route)
|
268
|
+
# rails engine in Rails 4.2 use additional
|
269
|
+
# ActionDispatch::Routing::Mapper::Constraints, which contain app
|
189
270
|
if route.app.respond_to?(:app) && route.app.respond_to?(:constraints)
|
190
271
|
route.app.app
|
191
272
|
else
|
@@ -193,101 +274,178 @@ class JsRoutes
|
|
193
274
|
end
|
194
275
|
end
|
195
276
|
|
196
|
-
def
|
197
|
-
|
198
|
-
nil
|
199
|
-
else
|
200
|
-
build_js(route, parent_route)
|
201
|
-
end
|
277
|
+
def route_helpers_if_match(route, parent_route = nil)
|
278
|
+
JsRoute.new(@configuration, route, parent_route).helpers
|
202
279
|
end
|
203
280
|
|
204
|
-
|
205
|
-
|
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
|
+
|
295
|
+
attr_reader :configuration, :route, :parent_route
|
296
|
+
|
297
|
+
def initialize(configuration, route, parent_route = nil)
|
298
|
+
@configuration = configuration
|
299
|
+
@route = route
|
300
|
+
@parent_route = parent_route
|
301
|
+
end
|
206
302
|
|
207
|
-
|
208
|
-
|
209
|
-
|
303
|
+
def helpers
|
304
|
+
helper_types.map do |absolute|
|
305
|
+
[ documentation, helper_name(absolute), body(absolute) ]
|
306
|
+
end
|
307
|
+
end
|
210
308
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
route_arguments = route_js_arguments(route, parent_spec)
|
216
|
-
url_link = generate_url_link(name, route_name, route_arguments, route)
|
217
|
-
_ = <<-JS.strip!
|
218
|
-
// #{name.join('.')} => #{parent_spec}#{route.path.spec}
|
219
|
-
// function(#{build_params(route.required_parts)})
|
220
|
-
#{route_name}: Utils.route(#{route_arguments})#{",\n" + url_link if url_link.length > 0}
|
221
|
-
JS
|
222
|
-
end
|
309
|
+
def helper_types
|
310
|
+
return [] unless match_configuration?
|
311
|
+
@configuration[:url_links] ? [true, false] : [false]
|
312
|
+
end
|
223
313
|
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
end
|
229
|
-
default_options = route.defaults.select do |part, _|
|
230
|
-
FILTERED_DEFAULT_PARTS.exclude?(part) && URL_OPTIONS.include?(part) || parts_table[part]
|
231
|
-
end
|
232
|
-
[
|
233
|
-
# JS objects don't preserve the order of properties which is crucial,
|
234
|
-
# so array is a better choice.
|
235
|
-
parts_table.to_a,
|
236
|
-
default_options,
|
237
|
-
serialize(route.path.spec, parent_spec)
|
238
|
-
].map do |argument|
|
239
|
-
json(argument)
|
240
|
-
end.join(", ")
|
241
|
-
end
|
314
|
+
def body(absolute)
|
315
|
+
@configuration.dts? ?
|
316
|
+
definition_body : "__jsr.r(#{arguments(absolute).map{|a| json(a)}.join(', ')})"
|
317
|
+
end
|
242
318
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
end
|
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
|
249
324
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
end
|
325
|
+
def optional_parts_type
|
326
|
+
@optional_parts_type ||=
|
327
|
+
"{" + optional_parts.map {|p| "#{p}?: OptionalRouteParameter"}.join(', ') + "}"
|
328
|
+
end
|
255
329
|
|
256
|
-
|
257
|
-
self.class.json(string)
|
258
|
-
end
|
330
|
+
protected
|
259
331
|
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
end
|
332
|
+
def arguments(absolute)
|
333
|
+
absolute ? [*base_arguments, true] : base_arguments
|
334
|
+
end
|
264
335
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
]
|
336
|
+
def match_configuration?
|
337
|
+
!match?(@configuration[:exclude]) && match?(@configuration[:include])
|
338
|
+
end
|
339
|
+
|
340
|
+
def base_name
|
341
|
+
@base_name ||= parent_route ?
|
342
|
+
[parent_route.name, route.name].join('_') : route.name
|
343
|
+
end
|
344
|
+
|
345
|
+
def parent_spec
|
346
|
+
parent_route&.path&.spec
|
347
|
+
end
|
348
|
+
|
349
|
+
def spec
|
350
|
+
route.path.spec
|
281
351
|
end
|
282
|
-
result
|
283
|
-
end
|
284
352
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
353
|
+
def json(value)
|
354
|
+
JsRoutes.json(value)
|
355
|
+
end
|
356
|
+
|
357
|
+
def helper_name(absolute)
|
358
|
+
suffix = absolute ? :url : @configuration[:compact] ? nil : :path
|
359
|
+
apply_case(base_name, suffix)
|
360
|
+
end
|
361
|
+
|
362
|
+
def documentation
|
363
|
+
return nil unless @configuration[:documentation]
|
364
|
+
<<-JS
|
365
|
+
/**
|
366
|
+
* Generates rails route to
|
367
|
+
* #{parent_spec}#{spec}#{documentation_params}
|
368
|
+
* @param {object | undefined} options
|
369
|
+
* @returns {string} route path
|
370
|
+
*/
|
371
|
+
JS
|
372
|
+
end
|
373
|
+
|
374
|
+
def required_parts
|
375
|
+
route.required_parts
|
376
|
+
end
|
377
|
+
|
378
|
+
def optional_parts
|
379
|
+
route.path.optional_names
|
380
|
+
end
|
381
|
+
|
382
|
+
def base_arguments
|
383
|
+
@base_arguments ||= [parts_table, serialize(spec, parent_spec)]
|
384
|
+
end
|
385
|
+
|
386
|
+
def parts_table
|
387
|
+
parts_table = {}
|
388
|
+
route.parts.each do |part, hash|
|
389
|
+
parts_table[part] ||= {}
|
390
|
+
if required_parts.include?(part)
|
391
|
+
# Using shortened keys to reduce js file size
|
392
|
+
parts_table[part][:r] = true
|
393
|
+
end
|
394
|
+
end
|
395
|
+
route.defaults.each do |part, value|
|
396
|
+
if FILTERED_DEFAULT_PARTS.exclude?(part) &&
|
397
|
+
URL_OPTIONS.include?(part) || parts_table[part]
|
398
|
+
parts_table[part] ||= {}
|
399
|
+
# Using shortened keys to reduce js file size
|
400
|
+
parts_table[part][:d] = value
|
401
|
+
end
|
402
|
+
end
|
403
|
+
parts_table
|
404
|
+
end
|
405
|
+
|
406
|
+
def documentation_params
|
407
|
+
required_parts.map do |param|
|
408
|
+
"\n * @param {any} #{apply_case(param)}"
|
409
|
+
end.join
|
410
|
+
end
|
411
|
+
|
412
|
+
def match?(matchers)
|
413
|
+
Array(matchers).any? { |regex| base_name =~ regex }
|
414
|
+
end
|
415
|
+
|
416
|
+
def apply_case(*values)
|
417
|
+
value = values.compact.map(&:to_s).join('_')
|
418
|
+
@configuration[:camel_case] ? value.camelize(:lower) : value
|
419
|
+
end
|
420
|
+
|
421
|
+
# This function serializes Journey route into JSON structure
|
422
|
+
# We do not use Hash for human readable serialization
|
423
|
+
# And preffer Array serialization because it is shorter.
|
424
|
+
# Routes.js file will be smaller.
|
425
|
+
def serialize(spec, parent_spec=nil)
|
426
|
+
return nil unless spec
|
427
|
+
# Rails 4 globbing requires * removal
|
428
|
+
return spec.tr(':*', '') if spec.is_a?(String)
|
429
|
+
|
430
|
+
result = serialize_spec(spec, parent_spec)
|
431
|
+
if parent_spec && result[1].is_a?(String) && parent_spec.type != :SLASH
|
432
|
+
result = [
|
433
|
+
# We encode node symbols as integer
|
434
|
+
# to reduce the routes.js file size
|
435
|
+
NODE_TYPES[:CAT],
|
436
|
+
serialize_spec(parent_spec),
|
437
|
+
result
|
438
|
+
]
|
439
|
+
end
|
440
|
+
result
|
441
|
+
end
|
442
|
+
|
443
|
+
def serialize_spec(spec, parent_spec = nil)
|
444
|
+
[
|
445
|
+
NODE_TYPES[spec.type],
|
446
|
+
serialize(spec.left, parent_spec),
|
447
|
+
spec.respond_to?(:right) ? serialize(spec.right) : nil
|
448
|
+
].compact
|
449
|
+
end
|
291
450
|
end
|
292
451
|
end
|
293
|
-
|
data/lib/routes.d.ts
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
/**
|
2
|
+
* File generated by js-routes RubyVariables.GEM_VERSION
|
3
|
+
* Based on Rails RubyVariables.RAILS_VERSION routes of RubyVariables.APP_CLASS
|
4
|
+
*/
|
5
|
+
declare type Optional<T> = {
|
6
|
+
[P in keyof T]?: T[P] | null;
|
7
|
+
};
|
8
|
+
declare type BaseRouteParameter = string | boolean | Date | number;
|
9
|
+
declare type MethodRouteParameter = BaseRouteParameter | (() => BaseRouteParameter);
|
10
|
+
declare type ModelRouteParameter = {
|
11
|
+
id: MethodRouteParameter;
|
12
|
+
} | {
|
13
|
+
to_param: MethodRouteParameter;
|
14
|
+
} | {
|
15
|
+
toParam: MethodRouteParameter;
|
16
|
+
};
|
17
|
+
declare type RequiredRouteParameter = BaseRouteParameter | ModelRouteParameter;
|
18
|
+
declare type OptionalRouteParameter = undefined | null | RequiredRouteParameter;
|
19
|
+
declare type QueryRouteParameter = OptionalRouteParameter | QueryRouteParameter[] | {
|
20
|
+
[k: string]: QueryRouteParameter;
|
21
|
+
};
|
22
|
+
declare type RouteParameters = Record<string, QueryRouteParameter>;
|
23
|
+
declare type Serializable = Record<string, unknown>;
|
24
|
+
declare type Serializer = (value: Serializable) => string;
|
25
|
+
declare type RouteHelperExtras = {
|
26
|
+
requiredParams(): string[];
|
27
|
+
toString(): string;
|
28
|
+
};
|
29
|
+
declare type RequiredParameters<T extends number> = T extends 1 ? [RequiredRouteParameter] : T extends 2 ? [RequiredRouteParameter, RequiredRouteParameter] : T extends 3 ? [RequiredRouteParameter, RequiredRouteParameter, RequiredRouteParameter] : T extends 4 ? [
|
30
|
+
RequiredRouteParameter,
|
31
|
+
RequiredRouteParameter,
|
32
|
+
RequiredRouteParameter,
|
33
|
+
RequiredRouteParameter
|
34
|
+
] : RequiredRouteParameter[];
|
35
|
+
declare type RouteHelperOptions<T extends string> = RouteOptions & Optional<Record<T, OptionalRouteParameter>>;
|
36
|
+
declare type RouteHelper<T extends number = number, U extends string = string> = ((...args: [...RequiredParameters<T>, RouteHelperOptions<U>]) => string) & RouteHelperExtras;
|
37
|
+
declare type RouteHelpers = Record<string, RouteHelper>;
|
38
|
+
declare type Configuration = {
|
39
|
+
prefix: string;
|
40
|
+
default_url_options: RouteParameters;
|
41
|
+
special_options_key: string;
|
42
|
+
serializer: Serializer;
|
43
|
+
};
|
44
|
+
interface RouterExposedMethods {
|
45
|
+
config(): Configuration;
|
46
|
+
configure(arg: Partial<Configuration>): Configuration;
|
47
|
+
serialize: Serializer;
|
48
|
+
}
|
49
|
+
declare type KeywordUrlOptions = Optional<{
|
50
|
+
host: string;
|
51
|
+
protocol: string;
|
52
|
+
subdomain: string;
|
53
|
+
port: string | number;
|
54
|
+
anchor: string;
|
55
|
+
trailing_slash: boolean;
|
56
|
+
}>;
|
57
|
+
declare type RouteOptions = KeywordUrlOptions & RouteParameters;
|
58
|
+
declare type PartsTable = Record<string, {
|
59
|
+
r?: boolean;
|
60
|
+
d?: OptionalRouteParameter;
|
61
|
+
}>;
|
62
|
+
declare type ModuleType = "CJS" | "AMD" | "UMD" | "ESM" | "DTS" | "NIL";
|
63
|
+
declare const RubyVariables: {
|
64
|
+
PREFIX: string;
|
65
|
+
DEPRECATED_GLOBBING_BEHAVIOR: boolean;
|
66
|
+
SPECIAL_OPTIONS_KEY: string;
|
67
|
+
DEFAULT_URL_OPTIONS: RouteParameters;
|
68
|
+
SERIALIZER: Serializer;
|
69
|
+
NAMESPACE: string;
|
70
|
+
ROUTES_OBJECT: RouteHelpers;
|
71
|
+
MODULE_TYPE: ModuleType;
|
72
|
+
WRAPPER: <T>(callback: T) => T;
|
73
|
+
};
|
74
|
+
declare const define: undefined | (((arg: unknown[], callback: () => unknown) => void) & {
|
75
|
+
amd?: unknown;
|
76
|
+
});
|
77
|
+
declare const module: {
|
78
|
+
exports: any;
|
79
|
+
} | undefined;
|