js-routes 1.4.13 → 2.0.3

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.
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.exists?(webpacker_dir) && defined?(::Sprockets) ? sprockets_file : webpacker_file
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
- 'ROUTES' => js_routes,
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
- end
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 js_routes
174
- js_routes = named_routes.sort_by(&:first).flat_map do |_, route|
175
- [build_route_if_match(route)] + mounted_app_routes(route)
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.map do |_, engine_route|
185
- build_route_if_match(engine_route, route)
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 build_route_if_match(route, parent_route = nil)
203
- if any_match?(route, parent_route, @configuration[:exclude]) ||
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
- def any_match?(route, parent_route, matchers)
212
- full_route = [parent_route.try(:name), route.name].compact.join('_')
231
+ class JsRoute #:nodoc:
232
+ attr_reader :configuration, :route, :parent_route
213
233
 
214
- matchers = Array(matchers)
215
- matchers.any? { |regex| full_route =~ regex }
216
- end
234
+ def initialize(configuration, route, parent_route = nil)
235
+ @configuration = configuration
236
+ @route = route
237
+ @parent_route = parent_route
238
+ end
217
239
 
218
- def build_js(route, parent_route)
219
- name = [parent_route.try(:name), route.name].compact
220
- route_name = generate_route_name(name, (:path unless @configuration[:compact]))
221
- parent_spec = parent_route.try(:path).try(:spec)
222
- route_arguments = route_js_arguments(route, parent_spec)
223
- url_link = generate_url_link(name, route_arguments)
224
- <<-JS.strip!
225
- // #{name.join('.')} => #{parent_spec}#{route.path.spec}
226
- // function(#{build_params(route.required_parts)})
227
- #{route_name}: Utils.route(#{route_arguments})#{",\n" + url_link if url_link.length > 0}
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
- def route_js_arguments(route, parent_spec)
232
- required_parts = route.required_parts
233
- parts_table = route.parts.each_with_object({}) do |part, hash|
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
- def generate_url_link(name, route_arguments)
252
- return '' unless @configuration[:url_links]
255
+ def arguments(absolute)
256
+ absolute ? base_arguments + [json(true)] : base_arguments
257
+ end
253
258
 
254
- <<-JS.strip!
255
- #{generate_route_name(name, :url)}: Utils.route(#{route_arguments}, true)
256
- JS
257
- end
259
+ def match_configuration?
260
+ !match?(@configuration[:exclude]) && match?(@configuration[:include])
261
+ end
258
262
 
259
- def generate_route_name(*parts)
260
- route_name = parts.compact.join('_')
261
- @configuration[:camel_case] ? route_name.camelize(:lower) : route_name
262
- end
263
+ def base_name
264
+ @base_name ||= apply_case(parent_route&.name, route.name)
265
+ end
263
266
 
264
- def json(string)
265
- self.class.json(string)
266
- end
267
+ def parent_spec
268
+ parent_route&.path&.spec
269
+ end
267
270
 
268
- def build_params(required_parts)
269
- params = required_parts + [LAST_OPTIONS_KEY]
270
- params.join(', ')
271
- end
271
+ def spec
272
+ route.path.spec
273
+ end
272
274
 
273
- # This function serializes Journey route into JSON structure
274
- # We do not use Hash for human readable serialization
275
- # And preffer Array serialization because it is shorter.
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
- def serialize_spec(spec, parent_spec = nil)
296
- [
297
- NODE_TYPES[spec.type],
298
- serialize(spec.left, parent_spec),
299
- spec.respond_to?(:right) && serialize(spec.right)
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
@@ -1,3 +1,3 @@
1
1
  class JsRoutes
2
- VERSION = "1.4.13"
2
+ VERSION = "2.0.3"
3
3
  end
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,521 +1,487 @@
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
- (function() {
7
- var DeprecatedGlobbingBehavior, NodeTypes, ParameterMissing, ReservedOptions, SpecialOptionsKey, UriEncoderSegmentRegex, Utils, result,
8
- hasProp = {}.hasOwnProperty,
9
- slice = [].slice;
10
-
11
- ParameterMissing = function(message, fileName, lineNumber) {
12
- var instance;
13
- instance = new Error(message, fileName, lineNumber);
14
- if (Object.setPrototypeOf) {
15
- Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
16
- } else {
17
- instance.__proto__ = this.__proto__;
18
- }
19
- if (Error.captureStackTrace) {
20
- Error.captureStackTrace(instance, ParameterMissing);
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
+ }
21
64
  }
22
- return instance;
23
- };
24
-
25
- ParameterMissing.prototype = Object.create(Error.prototype, {
26
- constructor: {
27
- value: Error,
28
- enumerable: false,
29
- writable: true,
30
- configurable: true
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
+ const 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
+ return left_part + right_part;
278
+ }
279
+ visit_symbol(
280
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
281
+ [_type, key], parameters, optional) {
282
+ const value = this.path_identifier(parameters[key]);
283
+ delete parameters[key];
284
+ if (value.length) {
285
+ return this.encode_segment(value);
286
+ }
287
+ if (optional) {
288
+ return "";
289
+ }
290
+ else {
291
+ throw new ParametersMissing(key);
292
+ }
293
+ }
294
+ encode_segment(segment) {
295
+ return segment.replace(UriEncoderSegmentRegex, function (str) {
296
+ return encodeURIComponent(str);
297
+ });
298
+ }
299
+ is_optional_node(node) {
300
+ return [NodeTypes.STAR, NodeTypes.SYMBOL, NodeTypes.CAT].includes(node);
301
+ }
302
+ build_path_spec(route, wildcard = false) {
303
+ let key;
304
+ switch (route[0]) {
305
+ case NodeTypes.GROUP:
306
+ return "(" + this.build_path_spec(route[1]) + ")";
307
+ case NodeTypes.CAT:
308
+ return (this.build_path_spec(route[1]) + this.build_path_spec(route[2]));
309
+ case NodeTypes.STAR:
310
+ return this.build_path_spec(route[1], true);
311
+ case NodeTypes.SYMBOL:
312
+ key = route[1];
313
+ if (wildcard) {
314
+ return (key.startsWith("*") ? "" : "*") + key;
315
+ }
316
+ else {
317
+ return ":" + key;
318
+ }
319
+ break;
320
+ case NodeTypes.SLASH:
321
+ case NodeTypes.DOT:
322
+ case NodeTypes.LITERAL:
323
+ return route[1];
324
+ default:
325
+ throw new Error("Unknown Rails node type");
326
+ }
327
+ }
328
+ visit_globbing(route, parameters, optional) {
329
+ const key = route[1];
330
+ let value = parameters[key];
331
+ delete parameters[key];
332
+ if (this.is_nullable(value)) {
333
+ return this.visit(route, parameters, optional);
334
+ }
335
+ if (this.is_array(value)) {
336
+ value = value.join("/");
337
+ }
338
+ const result = this.path_identifier(value);
339
+ return DeprecatedGlobbingBehavior ? result : encodeURI(result);
340
+ }
341
+ get_prefix() {
342
+ const prefix = this.configuration.prefix;
343
+ return prefix.match("/$")
344
+ ? prefix.substring(0, prefix.length - 1)
345
+ : prefix;
346
+ }
347
+ route(parts_table, route_spec, absolute = false) {
348
+ const required_params = [];
349
+ const parts = [];
350
+ const default_options = {};
351
+ for (const [part, { r: required, d: value }] of Object.entries(parts_table)) {
352
+ parts.push(part);
353
+ if (required) {
354
+ required_params.push(part);
355
+ }
356
+ if (this.is_not_nullable(value)) {
357
+ default_options[part] = value;
358
+ }
359
+ }
360
+ const result = (...args) => {
361
+ return this.build_route(parts, required_params, default_options, route_spec, absolute, args);
362
+ };
363
+ result.requiredParams = () => required_params;
364
+ result.toString = () => {
365
+ return this.build_path_spec(route_spec);
366
+ };
367
+ return result;
368
+ }
369
+ route_url(route_defaults) {
370
+ const hostname = route_defaults.host || this.current_host();
371
+ if (!hostname) {
372
+ return "";
373
+ }
374
+ const subdomain = route_defaults.subdomain
375
+ ? route_defaults.subdomain + "."
376
+ : "";
377
+ const protocol = route_defaults.protocol || this.current_protocol();
378
+ let port = route_defaults.port ||
379
+ (!route_defaults.host ? this.current_port() : undefined);
380
+ port = port ? ":" + port : "";
381
+ return protocol + "://" + subdomain + hostname + port;
382
+ }
383
+ has_location() {
384
+ return this.is_not_nullable(window) && !!window.location;
385
+ }
386
+ current_host() {
387
+ if (this.has_location()) {
388
+ return window.location.hostname;
389
+ }
390
+ else {
391
+ return null;
392
+ }
393
+ }
394
+ current_protocol() {
395
+ if (this.has_location() && window.location.protocol !== "") {
396
+ return window.location.protocol.replace(/:$/, "");
397
+ }
398
+ else {
399
+ return "http";
400
+ }
401
+ }
402
+ current_port() {
403
+ if (this.has_location() && window.location.port !== "") {
404
+ return window.location.port;
405
+ }
406
+ else {
407
+ return "";
408
+ }
409
+ }
410
+ is_object(value) {
411
+ return (typeof value === "object" &&
412
+ Object.prototype.toString.call(value) === "[object Object]");
413
+ }
414
+ is_array(object) {
415
+ return object instanceof Array;
416
+ }
417
+ is_callable(object) {
418
+ return typeof object === "function" && !!object.call;
419
+ }
420
+ is_reserved_option(key) {
421
+ return ReservedOptions.includes(key);
422
+ }
423
+ namespace(object, namespace, routes) {
424
+ const parts = (namespace === null || namespace === void 0 ? void 0 : namespace.split(".")) || [];
425
+ if (parts.length === 0) {
426
+ return routes;
427
+ }
428
+ for (let index = 0; index < parts.length; index++) {
429
+ const part = parts[index];
430
+ if (index < parts.length - 1) {
431
+ object = object[part] || (object[part] = {});
432
+ }
433
+ else {
434
+ return (object[part] = routes);
435
+ }
436
+ }
437
+ }
438
+ configure(new_config) {
439
+ this.configuration = { ...this.configuration, ...new_config };
440
+ return this.configuration;
441
+ }
442
+ config() {
443
+ return { ...this.configuration };
444
+ }
445
+ is_module_supported(name) {
446
+ return ModuleReferences[name].support();
447
+ }
448
+ ensure_module_supported(name) {
449
+ if (!this.is_module_supported(name)) {
450
+ throw new Error(`${name} is not supported by runtime`);
451
+ }
452
+ }
453
+ define_module(name, module) {
454
+ if (!name) {
455
+ return;
456
+ }
457
+ this.ensure_module_supported(name);
458
+ ModuleReferences[name].define(module);
459
+ }
31
460
  }
32
- });
33
-
34
- if (Object.setPrototypeOf) {
35
- Object.setPrototypeOf(ParameterMissing, Error);
36
- } else {
37
- ParameterMissing.__proto__ = Error;
38
- }
39
-
40
- NodeTypes = NODE_TYPES;
41
-
42
- DeprecatedGlobbingBehavior = DEPRECATED_GLOBBING_BEHAVIOR;
43
-
44
- SpecialOptionsKey = SPECIAL_OPTIONS_KEY;
45
-
46
- UriEncoderSegmentRegex = /[^a-zA-Z0-9\-\._~!\$&'\(\)\*\+,;=:@]/g;
47
-
48
- ReservedOptions = ['anchor', 'trailing_slash', 'subdomain', 'host', 'port', 'protocol'];
49
-
50
- Utils = {
51
- configuration: {
52
- prefix: PREFIX,
53
- default_url_options: DEFAULT_URL_OPTIONS,
54
- special_options_key: SPECIAL_OPTIONS_KEY,
55
- serializer: SERIALIZER
56
- },
57
- default_serializer: function(object, prefix) {
58
- var element, i, j, key, len, prop, s;
59
- if (prefix == null) {
60
- prefix = null;
61
- }
62
- if (object == null) {
63
- return "";
64
- }
65
- if (!prefix && !(this.get_object_type(object) === "object")) {
66
- throw new Error("Url parameters should be a javascript hash");
67
- }
68
- s = [];
69
- switch (this.get_object_type(object)) {
70
- case "array":
71
- for (i = j = 0, len = object.length; j < len; i = ++j) {
72
- element = object[i];
73
- s.push(this.default_serializer(element, prefix + "[]"));
74
- }
75
- break;
76
- case "object":
77
- for (key in object) {
78
- if (!hasProp.call(object, key)) continue;
79
- prop = object[key];
80
- if ((prop == null) && (prefix != null)) {
81
- prop = "";
82
- }
83
- if (prop != null) {
84
- if (prefix != null) {
85
- key = prefix + "[" + key + "]";
86
- }
87
- s.push(this.default_serializer(prop, key));
88
- }
89
- }
90
- break;
91
- default:
92
- if (object != null) {
93
- s.push((encodeURIComponent(prefix.toString())) + "=" + (encodeURIComponent(object.toString())));
94
- }
95
- }
96
- if (!s.length) {
97
- return "";
98
- }
99
- return s.join("&");
100
- },
101
- serialize: function(object) {
102
- var custom_serializer;
103
- custom_serializer = this.configuration.serializer;
104
- if ((custom_serializer != null) && this.get_object_type(custom_serializer) === "function") {
105
- return custom_serializer(object);
106
- } else {
107
- return this.default_serializer(object);
108
- }
109
- },
110
- clean_path: function(path) {
111
- var last_index;
112
- path = path.split("://");
113
- last_index = path.length - 1;
114
- path[last_index] = path[last_index].replace(/\/+/g, "/");
115
- return path.join("://");
116
- },
117
- extract_options: function(number_of_params, args) {
118
- var last_el, options;
119
- last_el = args[args.length - 1];
120
- if ((args.length > number_of_params && last_el === void 0) || ((last_el != null) && "object" === this.get_object_type(last_el) && !this.looks_like_serialized_model(last_el))) {
121
- options = args.pop() || {};
122
- delete options[this.configuration.special_options_key];
123
- return options;
124
- } else {
125
- return {};
126
- }
127
- },
128
- looks_like_serialized_model: function(object) {
129
- return !object[this.configuration.special_options_key] && ("id" in object || "to_param" in object);
130
- },
131
- path_identifier: function(object) {
132
- var property;
133
- if (object === 0) {
134
- return "0";
135
- }
136
- if (!object) {
137
- return "";
138
- }
139
- property = object;
140
- if (this.get_object_type(object) === "object") {
141
- if ("to_param" in object) {
142
- if (object.to_param == null) {
143
- throw new ParameterMissing("Route parameter missing: to_param");
144
- }
145
- property = object.to_param;
146
- } else if ("id" in object) {
147
- if (object.id == null) {
148
- throw new ParameterMissing("Route parameter missing: id");
149
- }
150
- property = object.id;
151
- } else {
152
- property = object;
153
- }
154
- if (this.get_object_type(property) === "function") {
155
- property = property.call(object);
156
- }
157
- }
158
- return property.toString();
159
- },
160
- clone: function(obj) {
161
- var attr, copy, key;
162
- if ((obj == null) || "object" !== this.get_object_type(obj)) {
163
- return obj;
164
- }
165
- copy = obj.constructor();
166
- for (key in obj) {
167
- if (!hasProp.call(obj, key)) continue;
168
- attr = obj[key];
169
- copy[key] = attr;
170
- }
171
- return copy;
172
- },
173
- merge: function() {
174
- var tap, xs;
175
- xs = 1 <= arguments.length ? slice.call(arguments, 0) : [];
176
- tap = function(o, fn) {
177
- fn(o);
178
- return o;
179
- };
180
- if ((xs != null ? xs.length : void 0) > 0) {
181
- return tap({}, function(m) {
182
- var j, k, len, results, v, x;
183
- results = [];
184
- for (j = 0, len = xs.length; j < len; j++) {
185
- x = xs[j];
186
- results.push((function() {
187
- var results1;
188
- results1 = [];
189
- for (k in x) {
190
- v = x[k];
191
- results1.push(m[k] = v);
192
- }
193
- return results1;
194
- })());
195
- }
196
- return results;
197
- });
198
- }
199
- },
200
- normalize_options: function(parts, required_parts, default_options, actual_parameters) {
201
- var i, j, key, len, options, part, parts_options, result, route_parts, url_parameters, use_all_parts, value;
202
- options = this.extract_options(parts.length, actual_parameters);
203
- if (actual_parameters.length > parts.length) {
204
- throw new Error("Too many parameters provided for path");
205
- }
206
- use_all_parts = actual_parameters.length > required_parts.length;
207
- parts_options = {};
208
- for (key in options) {
209
- if (!hasProp.call(options, key)) continue;
210
- use_all_parts = true;
211
- if (this.indexOf(parts, key) >= 0) {
212
- parts_options[key] = value;
213
- }
214
- }
215
- options = this.merge(this.configuration.default_url_options, default_options, options);
216
- result = {};
217
- url_parameters = {};
218
- result['url_parameters'] = url_parameters;
219
- for (key in options) {
220
- if (!hasProp.call(options, key)) continue;
221
- value = options[key];
222
- if (this.indexOf(ReservedOptions, key) >= 0) {
223
- result[key] = value;
224
- } else {
225
- url_parameters[key] = value;
226
- }
227
- }
228
- route_parts = use_all_parts ? parts : required_parts;
229
- i = 0;
230
- for (j = 0, len = route_parts.length; j < len; j++) {
231
- part = route_parts[j];
232
- if (i < actual_parameters.length) {
233
- if (!parts_options.hasOwnProperty(part)) {
234
- url_parameters[part] = actual_parameters[i];
235
- ++i;
236
- }
237
- }
238
- }
239
- return result;
240
- },
241
- build_route: function(parts, required_parts, default_options, route, full_url, args) {
242
- var options, parameters, result, url, url_params;
243
- args = Array.prototype.slice.call(args);
244
- options = this.normalize_options(parts, required_parts, default_options, args);
245
- parameters = options['url_parameters'];
246
- result = "" + (this.get_prefix()) + (this.visit(route, parameters));
247
- url = Utils.clean_path(result);
248
- if (options['trailing_slash'] === true) {
249
- url = url.replace(/(.*?)[\/]?$/, "$1/");
250
- }
251
- if ((url_params = this.serialize(parameters)).length) {
252
- url += "?" + url_params;
253
- }
254
- url += options.anchor ? "#" + options.anchor : "";
255
- if (full_url) {
256
- url = this.route_url(options) + url;
257
- }
258
- return url;
259
- },
260
- visit: function(route, parameters, optional) {
261
- var left, left_part, right, right_part, type, value;
262
- if (optional == null) {
263
- optional = false;
264
- }
265
- type = route[0], left = route[1], right = route[2];
266
- switch (type) {
267
- case NodeTypes.GROUP:
268
- return this.visit(left, parameters, true);
269
- case NodeTypes.STAR:
270
- return this.visit_globbing(left, parameters, true);
271
- case NodeTypes.LITERAL:
272
- case NodeTypes.SLASH:
273
- case NodeTypes.DOT:
274
- return left;
275
- case NodeTypes.CAT:
276
- left_part = this.visit(left, parameters, optional);
277
- right_part = this.visit(right, parameters, optional);
278
- if (optional && ((this.is_optional_node(left[0]) && !left_part) || ((this.is_optional_node(right[0])) && !right_part))) {
279
- return "";
280
- }
281
- return "" + left_part + right_part;
282
- case NodeTypes.SYMBOL:
283
- value = parameters[left];
284
- delete parameters[left];
285
- if (value != null) {
286
- return this.encode_segment(this.path_identifier(value));
287
- }
288
- if (optional) {
289
- return "";
290
- } else {
291
- throw new ParameterMissing("Route parameter missing: " + left);
292
- }
293
- break;
294
- default:
295
- throw new Error("Unknown Rails node type");
296
- }
297
- },
298
- encode_segment: function(segment) {
299
- return segment.replace(UriEncoderSegmentRegex, function(str) {
300
- return encodeURIComponent(str);
301
- });
302
- },
303
- is_optional_node: function(node) {
304
- return this.indexOf([NodeTypes.STAR, NodeTypes.SYMBOL, NodeTypes.CAT], node) >= 0;
305
- },
306
- build_path_spec: function(route, wildcard) {
307
- var left, right, type;
308
- if (wildcard == null) {
309
- wildcard = false;
310
- }
311
- type = route[0], left = route[1], right = route[2];
312
- switch (type) {
313
- case NodeTypes.GROUP:
314
- return "(" + (this.build_path_spec(left)) + ")";
315
- case NodeTypes.CAT:
316
- return "" + (this.build_path_spec(left)) + (this.build_path_spec(right));
317
- case NodeTypes.STAR:
318
- return this.build_path_spec(left, true);
319
- case NodeTypes.SYMBOL:
320
- if (wildcard === true) {
321
- return "" + (left[0] === '*' ? '' : '*') + left;
322
- } else {
323
- return ":" + left;
324
- }
325
- break;
326
- case NodeTypes.SLASH:
327
- case NodeTypes.DOT:
328
- case NodeTypes.LITERAL:
329
- return left;
330
- default:
331
- throw new Error("Unknown Rails node type");
332
- }
333
- },
334
- visit_globbing: function(route, parameters, optional) {
335
- var left, right, type, value;
336
- type = route[0], left = route[1], right = route[2];
337
- value = parameters[left];
338
- delete parameters[left];
339
- if (value == null) {
340
- return this.visit(route, parameters, optional);
341
- }
342
- value = (function() {
343
- switch (this.get_object_type(value)) {
344
- case "array":
345
- return value.join("/");
346
- default:
347
- return value;
348
- }
349
- }).call(this);
350
- if (DeprecatedGlobbingBehavior) {
351
- return this.path_identifier(value);
352
- } else {
353
- return encodeURI(this.path_identifier(value));
354
- }
355
- },
356
- get_prefix: function() {
357
- var prefix;
358
- prefix = this.configuration.prefix;
359
- if (prefix !== "") {
360
- prefix = (prefix.match("/$") ? prefix : prefix + "/");
361
- }
362
- return prefix;
363
- },
364
- route: function(parts_table, default_options, route_spec, full_url) {
365
- var j, len, part, parts, path_fn, ref, required, required_parts;
366
- required_parts = [];
367
- parts = [];
368
- for (j = 0, len = parts_table.length; j < len; j++) {
369
- ref = parts_table[j], part = ref[0], required = ref[1];
370
- parts.push(part);
371
- if (required) {
372
- required_parts.push(part);
373
- }
374
- }
375
- path_fn = function() {
376
- return Utils.build_route(parts, required_parts, default_options, route_spec, full_url, arguments);
377
- };
378
- path_fn.required_params = required_parts;
379
- path_fn.toString = function() {
380
- return Utils.build_path_spec(route_spec);
381
- };
382
- return path_fn;
383
- },
384
- route_url: function(route_defaults) {
385
- var hostname, port, protocol, subdomain;
386
- if (typeof route_defaults === 'string') {
387
- return route_defaults;
388
- }
389
- hostname = route_defaults.host || Utils.current_host();
390
- if (!hostname) {
391
- return '';
392
- }
393
- subdomain = route_defaults.subdomain ? route_defaults.subdomain + '.' : '';
394
- protocol = route_defaults.protocol || Utils.current_protocol();
395
- port = route_defaults.port || (!route_defaults.host ? Utils.current_port() : void 0);
396
- port = port ? ":" + port : '';
397
- return protocol + "://" + subdomain + hostname + port;
398
- },
399
- has_location: function() {
400
- return (typeof window !== "undefined" && window !== null ? window.location : void 0) != null;
401
- },
402
- current_host: function() {
403
- if (this.has_location()) {
404
- return window.location.hostname;
405
- } else {
406
- return null;
407
- }
408
- },
409
- current_protocol: function() {
410
- if (this.has_location() && window.location.protocol !== '') {
411
- return window.location.protocol.replace(/:$/, '');
412
- } else {
413
- return 'http';
414
- }
415
- },
416
- current_port: function() {
417
- if (this.has_location() && window.location.port !== '') {
418
- return window.location.port;
419
- } else {
420
- return '';
421
- }
422
- },
423
- _classToTypeCache: null,
424
- _classToType: function() {
425
- var j, len, name, ref;
426
- if (this._classToTypeCache != null) {
427
- return this._classToTypeCache;
428
- }
429
- this._classToTypeCache = {};
430
- ref = "Boolean Number String Function Array Date RegExp Object Error".split(" ");
431
- for (j = 0, len = ref.length; j < len; j++) {
432
- name = ref[j];
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);
461
+ const Utils = new UtilsClass();
462
+ // We want this helper name to be short
463
+ const __jsr = {
464
+ r(parts_table, route_spec, absolute) {
465
+ return Utils.route(parts_table, route_spec, absolute);
466
+ },
467
+ };
468
+ const result = {
469
+ ...__jsr,
470
+ configure: (config) => {
471
+ return Utils.configure(config);
472
+ },
473
+ config: () => {
474
+ return Utils.config();
475
+ },
476
+ serialize: (object) => {
477
+ return Utils.serialize(object);
478
+ },
479
+ ...RubyVariables.ROUTES_OBJECT,
480
+ };
481
+ Utils.namespace(Root, RubyVariables.NAMESPACE, result);
482
+ if (RubyVariables.MODULE_TYPE) {
483
+ Utils.define_module(RubyVariables.MODULE_TYPE, result);
504
484
  }
505
- };
506
-
507
- result = Utils.make();
508
-
509
- if (typeof define === "function" && define.amd) {
510
- define([], function() {
511
- return result;
512
- });
513
- } else if (typeof module !== "undefined" && module !== null) {
514
- module.exports = result;
515
- } else {
516
- Utils.namespace(this, NAMESPACE, result);
517
- }
518
-
519
- return result;
520
-
521
- }).call(this);
485
+ return result;
486
+ })(this);
487
+ //# sourceMappingURL=routes.js.map