js-routes 1.4.14 → 2.0.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/.eslintrc.js +15 -0
- data/.gitignore +3 -0
- data/.nvmrc +1 -0
- data/.travis.yml +2 -1
- data/CHANGELOG.md +27 -0
- data/Rakefile +5 -2
- data/Readme.md +90 -28
- data/VERSION_2_UPGRADE.md +61 -0
- data/js-routes.gemspec +6 -3
- data/lib/js_routes.rb +175 -105
- data/lib/js_routes/version.rb +1 -1
- data/lib/routes.d.ts +64 -0
- data/lib/routes.js +489 -524
- data/lib/routes.js.map +1 -0
- data/lib/routes.ts +693 -0
- data/package.json +36 -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 -4
- data/spec/js_routes/{common_js_compatibility_spec.rb → module_types/cjs_spec.rb} +5 -2
- data/spec/js_routes/module_types/esm_spec.rb +45 -0
- data/spec/js_routes/{generated_javascript_spec.rb → module_types/umd_spec.rb} +32 -21
- data/spec/js_routes/options_spec.rb +19 -6
- data/spec/js_routes/rails_routes_compatibility_spec.rb +69 -25
- data/spec/js_routes/zzz_last_post_rails_init_spec.rb +2 -2
- data/spec/spec_helper.rb +35 -17
- data/spec/support/routes.rb +9 -3
- data/tsconfig.json +32 -0
- data/yarn.lock +2145 -0
- metadata +24 -15
- data/lib/routes.js.coffee +0 -416
data/lib/js_routes.rb
CHANGED
@@ -3,6 +3,7 @@ if defined?(::Rails) && defined?(::Sprockets::Railtie)
|
|
3
3
|
require 'js_routes/engine'
|
4
4
|
end
|
5
5
|
require 'js_routes/version'
|
6
|
+
require 'active_support/core_ext/string/indent'
|
6
7
|
|
7
8
|
class JsRoutes
|
8
9
|
|
@@ -19,7 +20,7 @@ class JsRoutes
|
|
19
20
|
sprockets_dir = Rails.root.join('app','assets','javascripts')
|
20
21
|
sprockets_file = sprockets_dir.join('routes.js')
|
21
22
|
webpacker_file = webpacker_dir.join('routes.js')
|
22
|
-
!Dir.
|
23
|
+
!Dir.exist?(webpacker_dir) && defined?(::Sprockets) ? sprockets_file : webpacker_file
|
23
24
|
end,
|
24
25
|
prefix: -> { Rails.application.config.relative_url_root || "" },
|
25
26
|
url_links: false,
|
@@ -28,7 +29,9 @@ class JsRoutes
|
|
28
29
|
compact: false,
|
29
30
|
serializer: nil,
|
30
31
|
special_options_key: "_options",
|
31
|
-
application: -> { Rails.application }
|
32
|
+
application: -> { Rails.application },
|
33
|
+
module_type: 'ESM',
|
34
|
+
documentation: true,
|
32
35
|
} #:nodoc:
|
33
36
|
|
34
37
|
NODE_TYPES = {
|
@@ -42,7 +45,6 @@ class JsRoutes
|
|
42
45
|
DOT: 8
|
43
46
|
} #:nodoc:
|
44
47
|
|
45
|
-
LAST_OPTIONS_KEY = "options".freeze #:nodoc:
|
46
48
|
FILTERED_DEFAULT_PARTS = [:controller, :action] #:nodoc:
|
47
49
|
URL_OPTIONS = [:protocol, :domain, :host, :port, :subdomain] #:nodoc:
|
48
50
|
|
@@ -72,6 +74,10 @@ class JsRoutes
|
|
72
74
|
def to_hash
|
73
75
|
Hash[*members.zip(values).flatten(1)].symbolize_keys
|
74
76
|
end
|
77
|
+
|
78
|
+
def esm?
|
79
|
+
self.module_type === 'ESM'
|
80
|
+
end
|
75
81
|
end
|
76
82
|
|
77
83
|
#
|
@@ -83,11 +89,6 @@ class JsRoutes
|
|
83
89
|
configuration.tap(&block) if block
|
84
90
|
end
|
85
91
|
|
86
|
-
def options
|
87
|
-
ActiveSupport::Deprecation.warn('JsRoutes.options method is deprecated use JsRoutes.configuration instead')
|
88
|
-
configuration
|
89
|
-
end
|
90
|
-
|
91
92
|
def configuration
|
92
93
|
@configuration ||= Configuration.new
|
93
94
|
end
|
@@ -125,8 +126,7 @@ class JsRoutes
|
|
125
126
|
|
126
127
|
{
|
127
128
|
'GEM_VERSION' => JsRoutes::VERSION,
|
128
|
-
'
|
129
|
-
'NODE_TYPES' => json(NODE_TYPES),
|
129
|
+
'ROUTES_OBJECT' => routes_object,
|
130
130
|
'RAILS_VERSION' => ActionPack.version,
|
131
131
|
'DEPRECATED_GLOBBING_BEHAVIOR' => ActionPack::VERSION::MAJOR == 4 && ActionPack::VERSION::MINOR == 0,
|
132
132
|
|
@@ -136,9 +136,12 @@ class JsRoutes
|
|
136
136
|
'PREFIX' => json(@configuration.prefix),
|
137
137
|
'SPECIAL_OPTIONS_KEY' => json(@configuration.special_options_key),
|
138
138
|
'SERIALIZER' => @configuration.serializer || json(nil),
|
139
|
+
'MODULE_TYPE' => json(@configuration.module_type),
|
140
|
+
'WRAPPER' => @configuration.esm? ? 'const __jsr = ' : '',
|
139
141
|
}.inject(File.read(File.dirname(__FILE__) + "/routes.js")) do |js, (key, value)|
|
140
|
-
js.gsub!(key, value.to_s)
|
141
|
-
|
142
|
+
js.gsub!("RubyVariables.#{key}", value.to_s) ||
|
143
|
+
raise("Missing key #{key} in JS template")
|
144
|
+
end + routes_export
|
142
145
|
end
|
143
146
|
|
144
147
|
def generate!(file_name = nil)
|
@@ -166,23 +169,45 @@ class JsRoutes
|
|
166
169
|
@configuration.application
|
167
170
|
end
|
168
171
|
|
172
|
+
def json(string)
|
173
|
+
self.class.json(string)
|
174
|
+
end
|
175
|
+
|
169
176
|
def named_routes
|
170
177
|
application.routes.named_routes.to_a
|
171
178
|
end
|
172
179
|
|
173
|
-
def
|
174
|
-
|
175
|
-
|
180
|
+
def routes_object
|
181
|
+
return json({}) if @configuration.esm?
|
182
|
+
properties = routes_list.map do |comment, name, body|
|
183
|
+
"#{comment}#{name}: #{body}".indent(2)
|
184
|
+
end
|
185
|
+
"{\n" + properties.join(",\n\n") + "}\n"
|
186
|
+
end
|
187
|
+
|
188
|
+
STATIC_EXPORTS = [:configure, :config, :serialize].map do |name|
|
189
|
+
["", name, "__jsr.#{name}"]
|
190
|
+
end
|
191
|
+
|
192
|
+
def routes_export
|
193
|
+
return "" unless @configuration.esm?
|
194
|
+
[*STATIC_EXPORTS, *routes_list].map do |comment, name, body|
|
195
|
+
"#{comment}export const #{name} = #{body};"
|
196
|
+
end.join("\n\n")
|
197
|
+
end
|
198
|
+
|
199
|
+
def routes_list
|
200
|
+
named_routes.sort_by(&:first).flat_map do |_, route|
|
201
|
+
route_helpers_if_match(route) + mounted_app_routes(route)
|
176
202
|
end.compact
|
177
|
-
"{\n" + js_routes.join(",\n") + "}\n"
|
178
203
|
end
|
179
204
|
|
180
205
|
def mounted_app_routes(route)
|
181
206
|
rails_engine_app = get_app_from_route(route)
|
182
207
|
if rails_engine_app.respond_to?(:superclass) &&
|
183
208
|
rails_engine_app.superclass == Rails::Engine && !route.path.anchored
|
184
|
-
rails_engine_app.routes.named_routes.
|
185
|
-
|
209
|
+
rails_engine_app.routes.named_routes.flat_map do |_, engine_route|
|
210
|
+
route_helpers_if_match(engine_route, route)
|
186
211
|
end
|
187
212
|
else
|
188
213
|
[]
|
@@ -199,104 +224,149 @@ class JsRoutes
|
|
199
224
|
end
|
200
225
|
end
|
201
226
|
|
202
|
-
def
|
203
|
-
|
204
|
-
!any_match?(route, parent_route, @configuration[:include])
|
205
|
-
nil
|
206
|
-
else
|
207
|
-
build_js(route, parent_route)
|
208
|
-
end
|
227
|
+
def route_helpers_if_match(route, parent_route = nil)
|
228
|
+
JsRoute.new(@configuration, route, parent_route).helpers
|
209
229
|
end
|
210
230
|
|
211
|
-
|
212
|
-
|
231
|
+
class JsRoute #:nodoc:
|
232
|
+
attr_reader :configuration, :route, :parent_route
|
213
233
|
|
214
|
-
|
215
|
-
|
216
|
-
|
234
|
+
def initialize(configuration, route, parent_route = nil)
|
235
|
+
@configuration = configuration
|
236
|
+
@route = route
|
237
|
+
@parent_route = parent_route
|
238
|
+
end
|
217
239
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
JS
|
229
|
-
end
|
240
|
+
def helpers
|
241
|
+
unless match_configuration?
|
242
|
+
[]
|
243
|
+
else
|
244
|
+
[false, true].map do |absolute|
|
245
|
+
absolute && !@configuration[:url_links] ?
|
246
|
+
nil : [ documentation, helper_name(absolute), body(absolute) ]
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
230
250
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
hash[part] = required_parts.include?(part)
|
235
|
-
end
|
236
|
-
default_options = route.defaults.select do |part, _|
|
237
|
-
FILTERED_DEFAULT_PARTS.exclude?(part) &&
|
238
|
-
URL_OPTIONS.include?(part) || parts_table[part]
|
239
|
-
end
|
240
|
-
[
|
241
|
-
# JS objects don't preserve the order of properties which is crucial,
|
242
|
-
# so array is a better choice.
|
243
|
-
parts_table.to_a,
|
244
|
-
default_options,
|
245
|
-
serialize(route.path.spec, parent_spec)
|
246
|
-
].map do |argument|
|
247
|
-
json(argument)
|
248
|
-
end.join(', ')
|
249
|
-
end
|
251
|
+
def body(absolute)
|
252
|
+
"__jsr.r(#{arguments(absolute).join(', ')})"
|
253
|
+
end
|
250
254
|
|
251
|
-
|
252
|
-
|
255
|
+
def arguments(absolute)
|
256
|
+
absolute ? base_arguments + [json(true)] : base_arguments
|
257
|
+
end
|
253
258
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
end
|
259
|
+
def match_configuration?
|
260
|
+
!match?(@configuration[:exclude]) && match?(@configuration[:include])
|
261
|
+
end
|
258
262
|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
end
|
263
|
+
def base_name
|
264
|
+
@base_name ||= apply_case(parent_route&.name, route.name)
|
265
|
+
end
|
263
266
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
+
def parent_spec
|
268
|
+
parent_route&.path&.spec
|
269
|
+
end
|
267
270
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
end
|
271
|
+
def spec
|
272
|
+
route.path.spec
|
273
|
+
end
|
272
274
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
# Routes.js file will be smaller.
|
277
|
-
def serialize(spec, parent_spec=nil)
|
278
|
-
return nil unless spec
|
279
|
-
# Rails 4 globbing requires * removal
|
280
|
-
return spec.tr(':*', '') if spec.is_a?(String)
|
281
|
-
|
282
|
-
result = serialize_spec(spec, parent_spec)
|
283
|
-
if parent_spec && result[1].is_a?(String)
|
284
|
-
result = [
|
285
|
-
# We encode node symbols as integer
|
286
|
-
# to reduce the routes.js file size
|
287
|
-
NODE_TYPES[:CAT],
|
288
|
-
serialize_spec(parent_spec),
|
289
|
-
result
|
290
|
-
]
|
291
|
-
end
|
292
|
-
result
|
293
|
-
end
|
275
|
+
def json(value)
|
276
|
+
JsRoutes.json(value)
|
277
|
+
end
|
294
278
|
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
279
|
+
def helper_name(absolute)
|
280
|
+
suffix = absolute ? :url : @configuration[:compact] ? nil : :path
|
281
|
+
suffix ? apply_case(base_name, suffix) : base_name
|
282
|
+
end
|
283
|
+
|
284
|
+
def documentation
|
285
|
+
return nil unless @configuration[:documentation]
|
286
|
+
<<-JS
|
287
|
+
/**
|
288
|
+
* Generates rails route to
|
289
|
+
* #{parent_spec}#{spec}#{documentation_params}
|
290
|
+
* @param {object | undefined} options
|
291
|
+
* @returns {string} route path
|
292
|
+
*/
|
293
|
+
JS
|
294
|
+
end
|
295
|
+
|
296
|
+
def required_parts
|
297
|
+
route.required_parts
|
298
|
+
end
|
299
|
+
|
300
|
+
protected
|
301
|
+
|
302
|
+
def base_arguments
|
303
|
+
return @base_arguments if defined?(@base_arguments)
|
304
|
+
parts_table = {}
|
305
|
+
route.parts.each do |part, hash|
|
306
|
+
parts_table[part] ||= {}
|
307
|
+
if required_parts.include?(part)
|
308
|
+
# Using shortened keys to reduce js file size
|
309
|
+
parts_table[part][:r] = true
|
310
|
+
end
|
311
|
+
end
|
312
|
+
route.defaults.each do |part, value|
|
313
|
+
if FILTERED_DEFAULT_PARTS.exclude?(part) &&
|
314
|
+
URL_OPTIONS.include?(part) || parts_table[part]
|
315
|
+
parts_table[part] ||= {}
|
316
|
+
# Using shortened keys to reduce js file size
|
317
|
+
parts_table[part][:d] = value
|
318
|
+
end
|
319
|
+
end
|
320
|
+
@base_arguments = [
|
321
|
+
parts_table, serialize(spec, parent_spec)
|
322
|
+
].map do |argument|
|
323
|
+
json(argument)
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
def documentation_params
|
328
|
+
required_parts.map do |param|
|
329
|
+
"\n * @param {any} #{apply_case(param)}"
|
330
|
+
end.join
|
331
|
+
end
|
332
|
+
|
333
|
+
def match?(matchers)
|
334
|
+
Array(matchers).any? { |regex| base_name =~ regex }
|
335
|
+
end
|
336
|
+
|
337
|
+
def apply_case(*values)
|
338
|
+
value = values.compact.map(&:to_s).join('_')
|
339
|
+
@configuration[:camel_case] ? value.camelize(:lower) : value
|
340
|
+
end
|
341
|
+
|
342
|
+
# This function serializes Journey route into JSON structure
|
343
|
+
# We do not use Hash for human readable serialization
|
344
|
+
# And preffer Array serialization because it is shorter.
|
345
|
+
# Routes.js file will be smaller.
|
346
|
+
def serialize(spec, parent_spec=nil)
|
347
|
+
return nil unless spec
|
348
|
+
# Rails 4 globbing requires * removal
|
349
|
+
return spec.tr(':*', '') if spec.is_a?(String)
|
350
|
+
|
351
|
+
result = serialize_spec(spec, parent_spec)
|
352
|
+
if parent_spec && result[1].is_a?(String) && parent_spec.type != :SLASH
|
353
|
+
result = [
|
354
|
+
# We encode node symbols as integer
|
355
|
+
# to reduce the routes.js file size
|
356
|
+
NODE_TYPES[:CAT],
|
357
|
+
serialize_spec(parent_spec),
|
358
|
+
result
|
359
|
+
]
|
360
|
+
end
|
361
|
+
result
|
362
|
+
end
|
363
|
+
|
364
|
+
def serialize_spec(spec, parent_spec = nil)
|
365
|
+
[
|
366
|
+
NODE_TYPES[spec.type],
|
367
|
+
serialize(spec.left, parent_spec),
|
368
|
+
spec.respond_to?(:right) ? serialize(spec.right) : nil
|
369
|
+
].compact
|
370
|
+
end
|
301
371
|
end
|
302
372
|
end
|
data/lib/js_routes/version.rb
CHANGED
data/lib/routes.d.ts
ADDED
@@ -0,0 +1,64 @@
|
|
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 RouteParameter = unknown;
|
6
|
+
declare type RouteParameters = Record<string, RouteParameter>;
|
7
|
+
declare type Serializer = (value: unknown) => string;
|
8
|
+
declare type RouteHelper = {
|
9
|
+
(...args: RouteParameter[]): string;
|
10
|
+
requiredParams(): string[];
|
11
|
+
toString(): string;
|
12
|
+
};
|
13
|
+
declare type RouteHelpers = Record<string, RouteHelper>;
|
14
|
+
declare type Configuration = {
|
15
|
+
prefix: string;
|
16
|
+
default_url_options: RouteParameters;
|
17
|
+
special_options_key: string;
|
18
|
+
serializer: Serializer;
|
19
|
+
};
|
20
|
+
declare type Optional<T> = {
|
21
|
+
[P in keyof T]?: T[P] | null;
|
22
|
+
};
|
23
|
+
interface RouterExposedMethods {
|
24
|
+
config(): Configuration;
|
25
|
+
configure(arg: Partial<Configuration>): Configuration;
|
26
|
+
serialize: Serializer;
|
27
|
+
}
|
28
|
+
declare type KeywordUrlOptions = Optional<{
|
29
|
+
host: string;
|
30
|
+
protocol: string;
|
31
|
+
subdomain: string;
|
32
|
+
port: string;
|
33
|
+
anchor: string;
|
34
|
+
trailing_slash: boolean;
|
35
|
+
}>;
|
36
|
+
declare type PartsTable = Record<
|
37
|
+
string,
|
38
|
+
{
|
39
|
+
r?: boolean;
|
40
|
+
d?: unknown;
|
41
|
+
}
|
42
|
+
>;
|
43
|
+
declare type ModuleType = "CJS" | "AMD" | "UMD" | "ESM";
|
44
|
+
declare const RubyVariables: {
|
45
|
+
PREFIX: string;
|
46
|
+
DEPRECATED_GLOBBING_BEHAVIOR: boolean;
|
47
|
+
SPECIAL_OPTIONS_KEY: string;
|
48
|
+
DEFAULT_URL_OPTIONS: RouteParameters;
|
49
|
+
SERIALIZER: Serializer;
|
50
|
+
NAMESPACE: string;
|
51
|
+
ROUTES_OBJECT: RouteHelpers;
|
52
|
+
MODULE_TYPE: ModuleType | null;
|
53
|
+
WRAPPER: <T>(callback: T) => T;
|
54
|
+
};
|
55
|
+
declare const define:
|
56
|
+
| undefined
|
57
|
+
| (((arg: unknown[], callback: () => unknown) => void) & {
|
58
|
+
amd?: unknown;
|
59
|
+
});
|
60
|
+
declare const module:
|
61
|
+
| {
|
62
|
+
exports: any;
|
63
|
+
}
|
64
|
+
| undefined;
|
data/lib/routes.js
CHANGED
@@ -1,528 +1,493 @@
|
|
1
|
-
|
2
|
-
File generated by js-routes GEM_VERSION
|
3
|
-
Based on Rails RAILS_VERSION routes of APP_CLASS
|
1
|
+
/**
|
2
|
+
* File generated by js-routes RubyVariables.GEM_VERSION
|
3
|
+
* Based on Rails RubyVariables.RAILS_VERSION routes of RubyVariables.APP_CLASS
|
4
4
|
*/
|
5
|
-
|
6
|
-
(
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
5
|
+
RubyVariables.WRAPPER((that) => {
|
6
|
+
const hasProp = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
7
|
+
let NodeTypes;
|
8
|
+
(function (NodeTypes) {
|
9
|
+
NodeTypes[NodeTypes["GROUP"] = 1] = "GROUP";
|
10
|
+
NodeTypes[NodeTypes["CAT"] = 2] = "CAT";
|
11
|
+
NodeTypes[NodeTypes["SYMBOL"] = 3] = "SYMBOL";
|
12
|
+
NodeTypes[NodeTypes["OR"] = 4] = "OR";
|
13
|
+
NodeTypes[NodeTypes["STAR"] = 5] = "STAR";
|
14
|
+
NodeTypes[NodeTypes["LITERAL"] = 6] = "LITERAL";
|
15
|
+
NodeTypes[NodeTypes["SLASH"] = 7] = "SLASH";
|
16
|
+
NodeTypes[NodeTypes["DOT"] = 8] = "DOT";
|
17
|
+
})(NodeTypes || (NodeTypes = {}));
|
18
|
+
const Root = that;
|
19
|
+
const ModuleReferences = {
|
20
|
+
CJS: {
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
22
|
+
define: (routes) => (module.exports = routes),
|
23
|
+
support: () => typeof module === "object",
|
24
|
+
},
|
25
|
+
AMD: {
|
26
|
+
define: (routes) =>
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
28
|
+
define([], function () {
|
29
|
+
return routes;
|
30
|
+
}),
|
31
|
+
support: () => typeof define === "function" && !!define.amd,
|
32
|
+
},
|
33
|
+
UMD: {
|
34
|
+
define: (routes) => {
|
35
|
+
if (ModuleReferences.AMD.support()) {
|
36
|
+
ModuleReferences.AMD.define(routes);
|
37
|
+
}
|
38
|
+
else {
|
39
|
+
if (ModuleReferences.CJS.support()) {
|
40
|
+
try {
|
41
|
+
ModuleReferences.CJS.define(routes);
|
42
|
+
}
|
43
|
+
catch (error) {
|
44
|
+
if (error.name !== "TypeError")
|
45
|
+
throw error;
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
},
|
50
|
+
support: () => ModuleReferences.AMD.support() || ModuleReferences.CJS.support(),
|
51
|
+
},
|
52
|
+
ESM: {
|
53
|
+
define: () => null,
|
54
|
+
support: () => true,
|
55
|
+
},
|
56
|
+
};
|
57
|
+
class ParametersMissing extends Error {
|
58
|
+
constructor(...keys) {
|
59
|
+
super(`Route missing required keys: ${keys.join(", ")}`);
|
60
|
+
this.keys = keys;
|
61
|
+
Object.setPrototypeOf(this, Object.getPrototypeOf(this));
|
62
|
+
this.name = ParametersMissing.name;
|
63
|
+
}
|
31
64
|
}
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
this._classToTypeCache["[object " + name + "]"] = name.toLowerCase();
|
434
|
-
}
|
435
|
-
return this._classToTypeCache;
|
436
|
-
},
|
437
|
-
get_object_type: function(obj) {
|
438
|
-
if (this.jQuery && (this.jQuery.type != null)) {
|
439
|
-
return this.jQuery.type(obj);
|
440
|
-
}
|
441
|
-
if (obj == null) {
|
442
|
-
return "" + obj;
|
443
|
-
}
|
444
|
-
if (typeof obj === "object" || typeof obj === "function") {
|
445
|
-
return this._classToType()[Object.prototype.toString.call(obj)] || "object";
|
446
|
-
} else {
|
447
|
-
return typeof obj;
|
448
|
-
}
|
449
|
-
},
|
450
|
-
indexOf: function(array, element) {
|
451
|
-
if (Array.prototype.indexOf) {
|
452
|
-
return array.indexOf(element);
|
453
|
-
} else {
|
454
|
-
return this.indexOfImplementation(array, element);
|
455
|
-
}
|
456
|
-
},
|
457
|
-
indexOfImplementation: function(array, element) {
|
458
|
-
var el, i, j, len, result;
|
459
|
-
result = -1;
|
460
|
-
for (i = j = 0, len = array.length; j < len; i = ++j) {
|
461
|
-
el = array[i];
|
462
|
-
if (el === element) {
|
463
|
-
result = i;
|
464
|
-
}
|
465
|
-
}
|
466
|
-
return result;
|
467
|
-
},
|
468
|
-
namespace: function(root, namespace, routes) {
|
469
|
-
var index, j, len, part, parts;
|
470
|
-
parts = namespace ? namespace.split(".") : [];
|
471
|
-
if (parts.length === 0) {
|
472
|
-
return routes;
|
473
|
-
}
|
474
|
-
for (index = j = 0, len = parts.length; j < len; index = ++j) {
|
475
|
-
part = parts[index];
|
476
|
-
if (index < parts.length - 1) {
|
477
|
-
root = (root[part] || (root[part] = {}));
|
478
|
-
} else {
|
479
|
-
return root[part] = routes;
|
480
|
-
}
|
481
|
-
}
|
482
|
-
},
|
483
|
-
configure: function(new_config) {
|
484
|
-
return this.configuration = this.merge(this.configuration, new_config);
|
485
|
-
},
|
486
|
-
config: function() {
|
487
|
-
return this.clone(this.configuration);
|
488
|
-
},
|
489
|
-
make: function() {
|
490
|
-
var routes;
|
491
|
-
routes = ROUTES;
|
492
|
-
routes.configure = function(config) {
|
493
|
-
return Utils.configure(config);
|
494
|
-
};
|
495
|
-
routes.config = function() {
|
496
|
-
return Utils.config();
|
497
|
-
};
|
498
|
-
routes.default_serializer = function(object, prefix) {
|
499
|
-
return Utils.default_serializer(object, prefix);
|
500
|
-
};
|
501
|
-
return Object.assign({
|
502
|
-
"default": routes
|
503
|
-
}, routes);
|
65
|
+
const DeprecatedGlobbingBehavior = RubyVariables.DEPRECATED_GLOBBING_BEHAVIOR;
|
66
|
+
const UriEncoderSegmentRegex = /[^a-zA-Z0-9\-._~!$&'()*+,;=:@]/g;
|
67
|
+
const ReservedOptions = [
|
68
|
+
"anchor",
|
69
|
+
"trailing_slash",
|
70
|
+
"subdomain",
|
71
|
+
"host",
|
72
|
+
"port",
|
73
|
+
"protocol",
|
74
|
+
];
|
75
|
+
class UtilsClass {
|
76
|
+
constructor() {
|
77
|
+
this.configuration = {
|
78
|
+
prefix: RubyVariables.PREFIX,
|
79
|
+
default_url_options: RubyVariables.DEFAULT_URL_OPTIONS,
|
80
|
+
special_options_key: RubyVariables.SPECIAL_OPTIONS_KEY,
|
81
|
+
serializer: RubyVariables.SERIALIZER || this.default_serializer.bind(this),
|
82
|
+
};
|
83
|
+
}
|
84
|
+
default_serializer(value, prefix) {
|
85
|
+
if (this.is_nullable(value)) {
|
86
|
+
return "";
|
87
|
+
}
|
88
|
+
if (!prefix && !this.is_object(value)) {
|
89
|
+
throw new Error("Url parameters should be a javascript hash");
|
90
|
+
}
|
91
|
+
prefix = prefix || "";
|
92
|
+
const result = [];
|
93
|
+
if (this.is_array(value)) {
|
94
|
+
for (const element of value) {
|
95
|
+
result.push(this.default_serializer(element, prefix + "[]"));
|
96
|
+
}
|
97
|
+
}
|
98
|
+
else if (this.is_object(value)) {
|
99
|
+
for (let key in value) {
|
100
|
+
if (!hasProp(value, key))
|
101
|
+
continue;
|
102
|
+
let prop = value[key];
|
103
|
+
if (this.is_nullable(prop) && prefix) {
|
104
|
+
prop = "";
|
105
|
+
}
|
106
|
+
if (this.is_not_nullable(prop)) {
|
107
|
+
if (prefix) {
|
108
|
+
key = prefix + "[" + key + "]";
|
109
|
+
}
|
110
|
+
result.push(this.default_serializer(prop, key));
|
111
|
+
}
|
112
|
+
}
|
113
|
+
}
|
114
|
+
else {
|
115
|
+
if (this.is_not_nullable(value)) {
|
116
|
+
result.push(encodeURIComponent(prefix) + "=" + encodeURIComponent("" + value));
|
117
|
+
}
|
118
|
+
}
|
119
|
+
return result.join("&");
|
120
|
+
}
|
121
|
+
serialize(object) {
|
122
|
+
return this.configuration.serializer(object);
|
123
|
+
}
|
124
|
+
extract_options(number_of_params, args) {
|
125
|
+
const last_el = args[args.length - 1];
|
126
|
+
if ((args.length > number_of_params && last_el === 0) ||
|
127
|
+
(this.is_object(last_el) &&
|
128
|
+
!this.looks_like_serialized_model(last_el))) {
|
129
|
+
if (this.is_object(last_el)) {
|
130
|
+
delete last_el[this.configuration.special_options_key];
|
131
|
+
}
|
132
|
+
return {
|
133
|
+
args: args.slice(0, args.length - 1),
|
134
|
+
options: last_el,
|
135
|
+
};
|
136
|
+
}
|
137
|
+
else {
|
138
|
+
return { args, options: {} };
|
139
|
+
}
|
140
|
+
}
|
141
|
+
looks_like_serialized_model(object) {
|
142
|
+
return (this.is_object(object) &&
|
143
|
+
!object[this.configuration.special_options_key] &&
|
144
|
+
("id" in object || "to_param" in object || "toParam" in object));
|
145
|
+
}
|
146
|
+
path_identifier(object) {
|
147
|
+
const result = this.unwrap_path_identifier(object);
|
148
|
+
return this.is_nullable(result) || result === false ? "" : "" + result;
|
149
|
+
}
|
150
|
+
unwrap_path_identifier(object) {
|
151
|
+
let result = object;
|
152
|
+
if (!this.is_object(object)) {
|
153
|
+
return object;
|
154
|
+
}
|
155
|
+
if ("to_param" in object) {
|
156
|
+
result = object.to_param;
|
157
|
+
}
|
158
|
+
else if ("toParam" in object) {
|
159
|
+
result = object.toParam;
|
160
|
+
}
|
161
|
+
else if ("id" in object) {
|
162
|
+
result = object.id;
|
163
|
+
}
|
164
|
+
else {
|
165
|
+
result = object;
|
166
|
+
}
|
167
|
+
return this.is_callable(result) ? result.call(object) : result;
|
168
|
+
}
|
169
|
+
partition_parameters(parts, required_params, default_options, call_arguments) {
|
170
|
+
// eslint-disable-next-line prefer-const
|
171
|
+
let { args, options } = this.extract_options(parts.length, call_arguments);
|
172
|
+
if (args.length > parts.length) {
|
173
|
+
throw new Error("Too many parameters provided for path");
|
174
|
+
}
|
175
|
+
let use_all_parts = args.length > required_params.length;
|
176
|
+
const parts_options = {};
|
177
|
+
for (const key in options) {
|
178
|
+
const value = options[key];
|
179
|
+
if (!hasProp(options, key))
|
180
|
+
continue;
|
181
|
+
use_all_parts = true;
|
182
|
+
if (parts.includes(key)) {
|
183
|
+
parts_options[key] = value;
|
184
|
+
}
|
185
|
+
}
|
186
|
+
options = {
|
187
|
+
...this.configuration.default_url_options,
|
188
|
+
...default_options,
|
189
|
+
...options,
|
190
|
+
};
|
191
|
+
const keyword_parameters = {};
|
192
|
+
const query_parameters = {};
|
193
|
+
for (const key in options) {
|
194
|
+
if (!hasProp(options, key))
|
195
|
+
continue;
|
196
|
+
const value = options[key];
|
197
|
+
if (this.is_reserved_option(key)) {
|
198
|
+
keyword_parameters[key] = value;
|
199
|
+
}
|
200
|
+
else {
|
201
|
+
if (!this.is_nullable(value) &&
|
202
|
+
(value !== default_options[key] || required_params.includes(key))) {
|
203
|
+
query_parameters[key] = value;
|
204
|
+
}
|
205
|
+
}
|
206
|
+
}
|
207
|
+
const route_parts = use_all_parts ? parts : required_params;
|
208
|
+
let i = 0;
|
209
|
+
for (const part of route_parts) {
|
210
|
+
if (i < args.length) {
|
211
|
+
const value = args[i];
|
212
|
+
if (!hasProp(parts_options, part)) {
|
213
|
+
query_parameters[part] = value;
|
214
|
+
++i;
|
215
|
+
}
|
216
|
+
}
|
217
|
+
}
|
218
|
+
return { keyword_parameters, query_parameters };
|
219
|
+
}
|
220
|
+
build_route(parts, required_params, default_options, route, absolute, args) {
|
221
|
+
const { keyword_parameters, query_parameters, } = this.partition_parameters(parts, required_params, default_options, args);
|
222
|
+
const missing_params = required_params.filter((param) => !hasProp(query_parameters, param) ||
|
223
|
+
this.is_nullable(query_parameters[param]));
|
224
|
+
if (missing_params.length) {
|
225
|
+
throw new ParametersMissing(...missing_params);
|
226
|
+
}
|
227
|
+
let result = this.get_prefix() + this.visit(route, query_parameters);
|
228
|
+
if (keyword_parameters.trailing_slash) {
|
229
|
+
result = result.replace(/(.*?)[/]?$/, "$1/");
|
230
|
+
}
|
231
|
+
const url_params = this.serialize(query_parameters);
|
232
|
+
if (url_params.length) {
|
233
|
+
result += "?" + url_params;
|
234
|
+
}
|
235
|
+
result += keyword_parameters.anchor
|
236
|
+
? "#" + keyword_parameters.anchor
|
237
|
+
: "";
|
238
|
+
if (absolute) {
|
239
|
+
result = this.route_url(keyword_parameters) + result;
|
240
|
+
}
|
241
|
+
return result;
|
242
|
+
}
|
243
|
+
visit(route, parameters, optional = false) {
|
244
|
+
switch (route[0]) {
|
245
|
+
case NodeTypes.GROUP:
|
246
|
+
return this.visit(route[1], parameters, true);
|
247
|
+
case NodeTypes.CAT:
|
248
|
+
return this.visit_cat(route, parameters, optional);
|
249
|
+
case NodeTypes.SYMBOL:
|
250
|
+
return this.visit_symbol(route, parameters, optional);
|
251
|
+
case NodeTypes.STAR:
|
252
|
+
return this.visit_globbing(route[1], parameters, true);
|
253
|
+
case NodeTypes.LITERAL:
|
254
|
+
case NodeTypes.SLASH:
|
255
|
+
case NodeTypes.DOT:
|
256
|
+
return route[1];
|
257
|
+
default:
|
258
|
+
throw new Error("Unknown Rails node type");
|
259
|
+
}
|
260
|
+
}
|
261
|
+
is_not_nullable(object) {
|
262
|
+
return !this.is_nullable(object);
|
263
|
+
}
|
264
|
+
is_nullable(object) {
|
265
|
+
return object === undefined || object === null;
|
266
|
+
}
|
267
|
+
visit_cat(
|
268
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
269
|
+
[_type, left, right], parameters, optional) {
|
270
|
+
const left_part = this.visit(left, parameters, optional);
|
271
|
+
let right_part = this.visit(right, parameters, optional);
|
272
|
+
if (optional &&
|
273
|
+
((this.is_optional_node(left[0]) && !left_part) ||
|
274
|
+
(this.is_optional_node(right[0]) && !right_part))) {
|
275
|
+
return "";
|
276
|
+
}
|
277
|
+
// if left_part ends on '/' and right_part starts on '/'
|
278
|
+
if (left_part[left_part.length - 1] === '/' && right_part[0] === '/') {
|
279
|
+
// strip slash from right_part
|
280
|
+
// to prevent double slash
|
281
|
+
right_part = right_part.substring(1);
|
282
|
+
}
|
283
|
+
return left_part + right_part;
|
284
|
+
}
|
285
|
+
visit_symbol(
|
286
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
287
|
+
[_type, key], parameters, optional) {
|
288
|
+
const value = this.path_identifier(parameters[key]);
|
289
|
+
delete parameters[key];
|
290
|
+
if (value.length) {
|
291
|
+
return this.encode_segment(value);
|
292
|
+
}
|
293
|
+
if (optional) {
|
294
|
+
return "";
|
295
|
+
}
|
296
|
+
else {
|
297
|
+
throw new ParametersMissing(key);
|
298
|
+
}
|
299
|
+
}
|
300
|
+
encode_segment(segment) {
|
301
|
+
return segment.replace(UriEncoderSegmentRegex, function (str) {
|
302
|
+
return encodeURIComponent(str);
|
303
|
+
});
|
304
|
+
}
|
305
|
+
is_optional_node(node) {
|
306
|
+
return [NodeTypes.STAR, NodeTypes.SYMBOL, NodeTypes.CAT].includes(node);
|
307
|
+
}
|
308
|
+
build_path_spec(route, wildcard = false) {
|
309
|
+
let key;
|
310
|
+
switch (route[0]) {
|
311
|
+
case NodeTypes.GROUP:
|
312
|
+
return "(" + this.build_path_spec(route[1]) + ")";
|
313
|
+
case NodeTypes.CAT:
|
314
|
+
return (this.build_path_spec(route[1]) + this.build_path_spec(route[2]));
|
315
|
+
case NodeTypes.STAR:
|
316
|
+
return this.build_path_spec(route[1], true);
|
317
|
+
case NodeTypes.SYMBOL:
|
318
|
+
key = route[1];
|
319
|
+
if (wildcard) {
|
320
|
+
return (key.startsWith("*") ? "" : "*") + key;
|
321
|
+
}
|
322
|
+
else {
|
323
|
+
return ":" + key;
|
324
|
+
}
|
325
|
+
break;
|
326
|
+
case NodeTypes.SLASH:
|
327
|
+
case NodeTypes.DOT:
|
328
|
+
case NodeTypes.LITERAL:
|
329
|
+
return route[1];
|
330
|
+
default:
|
331
|
+
throw new Error("Unknown Rails node type");
|
332
|
+
}
|
333
|
+
}
|
334
|
+
visit_globbing(route, parameters, optional) {
|
335
|
+
const key = route[1];
|
336
|
+
let value = parameters[key];
|
337
|
+
delete parameters[key];
|
338
|
+
if (this.is_nullable(value)) {
|
339
|
+
return this.visit(route, parameters, optional);
|
340
|
+
}
|
341
|
+
if (this.is_array(value)) {
|
342
|
+
value = value.join("/");
|
343
|
+
}
|
344
|
+
const result = this.path_identifier(value);
|
345
|
+
return DeprecatedGlobbingBehavior ? result : encodeURI(result);
|
346
|
+
}
|
347
|
+
get_prefix() {
|
348
|
+
const prefix = this.configuration.prefix;
|
349
|
+
return prefix.match("/$")
|
350
|
+
? prefix.substring(0, prefix.length - 1)
|
351
|
+
: prefix;
|
352
|
+
}
|
353
|
+
route(parts_table, route_spec, absolute = false) {
|
354
|
+
const required_params = [];
|
355
|
+
const parts = [];
|
356
|
+
const default_options = {};
|
357
|
+
for (const [part, { r: required, d: value }] of Object.entries(parts_table)) {
|
358
|
+
parts.push(part);
|
359
|
+
if (required) {
|
360
|
+
required_params.push(part);
|
361
|
+
}
|
362
|
+
if (this.is_not_nullable(value)) {
|
363
|
+
default_options[part] = value;
|
364
|
+
}
|
365
|
+
}
|
366
|
+
const result = (...args) => {
|
367
|
+
return this.build_route(parts, required_params, default_options, route_spec, absolute, args);
|
368
|
+
};
|
369
|
+
result.requiredParams = () => required_params;
|
370
|
+
result.toString = () => {
|
371
|
+
return this.build_path_spec(route_spec);
|
372
|
+
};
|
373
|
+
return result;
|
374
|
+
}
|
375
|
+
route_url(route_defaults) {
|
376
|
+
const hostname = route_defaults.host || this.current_host();
|
377
|
+
if (!hostname) {
|
378
|
+
return "";
|
379
|
+
}
|
380
|
+
const subdomain = route_defaults.subdomain
|
381
|
+
? route_defaults.subdomain + "."
|
382
|
+
: "";
|
383
|
+
const protocol = route_defaults.protocol || this.current_protocol();
|
384
|
+
let port = route_defaults.port ||
|
385
|
+
(!route_defaults.host ? this.current_port() : undefined);
|
386
|
+
port = port ? ":" + port : "";
|
387
|
+
return protocol + "://" + subdomain + hostname + port;
|
388
|
+
}
|
389
|
+
has_location() {
|
390
|
+
return this.is_not_nullable(window) && !!window.location;
|
391
|
+
}
|
392
|
+
current_host() {
|
393
|
+
if (this.has_location()) {
|
394
|
+
return window.location.hostname;
|
395
|
+
}
|
396
|
+
else {
|
397
|
+
return null;
|
398
|
+
}
|
399
|
+
}
|
400
|
+
current_protocol() {
|
401
|
+
if (this.has_location() && window.location.protocol !== "") {
|
402
|
+
return window.location.protocol.replace(/:$/, "");
|
403
|
+
}
|
404
|
+
else {
|
405
|
+
return "http";
|
406
|
+
}
|
407
|
+
}
|
408
|
+
current_port() {
|
409
|
+
if (this.has_location() && window.location.port !== "") {
|
410
|
+
return window.location.port;
|
411
|
+
}
|
412
|
+
else {
|
413
|
+
return "";
|
414
|
+
}
|
415
|
+
}
|
416
|
+
is_object(value) {
|
417
|
+
return (typeof value === "object" &&
|
418
|
+
Object.prototype.toString.call(value) === "[object Object]");
|
419
|
+
}
|
420
|
+
is_array(object) {
|
421
|
+
return object instanceof Array;
|
422
|
+
}
|
423
|
+
is_callable(object) {
|
424
|
+
return typeof object === "function" && !!object.call;
|
425
|
+
}
|
426
|
+
is_reserved_option(key) {
|
427
|
+
return ReservedOptions.includes(key);
|
428
|
+
}
|
429
|
+
namespace(object, namespace, routes) {
|
430
|
+
const parts = (namespace === null || namespace === void 0 ? void 0 : namespace.split(".")) || [];
|
431
|
+
if (parts.length === 0) {
|
432
|
+
return routes;
|
433
|
+
}
|
434
|
+
for (let index = 0; index < parts.length; index++) {
|
435
|
+
const part = parts[index];
|
436
|
+
if (index < parts.length - 1) {
|
437
|
+
object = object[part] || (object[part] = {});
|
438
|
+
}
|
439
|
+
else {
|
440
|
+
return (object[part] = routes);
|
441
|
+
}
|
442
|
+
}
|
443
|
+
}
|
444
|
+
configure(new_config) {
|
445
|
+
this.configuration = { ...this.configuration, ...new_config };
|
446
|
+
return this.configuration;
|
447
|
+
}
|
448
|
+
config() {
|
449
|
+
return { ...this.configuration };
|
450
|
+
}
|
451
|
+
is_module_supported(name) {
|
452
|
+
return ModuleReferences[name].support();
|
453
|
+
}
|
454
|
+
ensure_module_supported(name) {
|
455
|
+
if (!this.is_module_supported(name)) {
|
456
|
+
throw new Error(`${name} is not supported by runtime`);
|
457
|
+
}
|
458
|
+
}
|
459
|
+
define_module(name, module) {
|
460
|
+
if (!name) {
|
461
|
+
return;
|
462
|
+
}
|
463
|
+
this.ensure_module_supported(name);
|
464
|
+
ModuleReferences[name].define(module);
|
465
|
+
}
|
504
466
|
}
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
467
|
+
const Utils = new UtilsClass();
|
468
|
+
// We want this helper name to be short
|
469
|
+
const __jsr = {
|
470
|
+
r(parts_table, route_spec, absolute) {
|
471
|
+
return Utils.route(parts_table, route_spec, absolute);
|
472
|
+
},
|
473
|
+
};
|
474
|
+
const result = {
|
475
|
+
...__jsr,
|
476
|
+
configure: (config) => {
|
477
|
+
return Utils.configure(config);
|
478
|
+
},
|
479
|
+
config: () => {
|
480
|
+
return Utils.config();
|
481
|
+
},
|
482
|
+
serialize: (object) => {
|
483
|
+
return Utils.serialize(object);
|
484
|
+
},
|
485
|
+
...RubyVariables.ROUTES_OBJECT,
|
486
|
+
};
|
487
|
+
Utils.namespace(Root, RubyVariables.NAMESPACE, result);
|
488
|
+
if (RubyVariables.MODULE_TYPE) {
|
489
|
+
Utils.define_module(RubyVariables.MODULE_TYPE, result);
|
521
490
|
}
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
return result;
|
527
|
-
|
528
|
-
}).call(this);
|
491
|
+
return result;
|
492
|
+
})(this);
|
493
|
+
//# sourceMappingURL=routes.js.map
|