js-routes 2.2.1 → 2.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/Readme.md +2 -1
- data/lib/js_routes/configuration.rb +111 -0
- data/lib/js_routes/engine.rb +28 -26
- data/lib/js_routes/generators/middleware.rb +1 -1
- data/lib/js_routes/instance.rb +173 -0
- data/lib/js_routes/middleware.rb +7 -3
- data/lib/js_routes/route.rb +1 -1
- data/lib/js_routes/version.rb +2 -2
- data/lib/js_routes.rb +8 -261
- data/lib/routes.d.ts +1 -1
- data/lib/routes.js +22 -27
- data/lib/routes.ts +21 -32
- data/spec/js_routes/default_serializer_spec.rb +4 -4
- data/spec/js_routes/module_types/amd_spec.rb +1 -1
- data/spec/js_routes/module_types/cjs_spec.rb +1 -1
- data/spec/js_routes/module_types/dts/routes.spec.d.ts +1 -1
- data/spec/js_routes/module_types/esm_spec.rb +2 -2
- data/spec/js_routes/module_types/nil_spec.rb +8 -7
- data/spec/js_routes/options_spec.rb +85 -82
- data/spec/js_routes/rails_routes_compatibility_spec.rb +127 -137
- data/spec/js_routes/route_specification_spec.rb +40 -0
- data/spec/spec_helper.rb +16 -4
- metadata +5 -2
data/lib/js_routes.rb
CHANGED
@@ -1,116 +1,12 @@
|
|
1
|
-
|
2
|
-
require "pathname"
|
3
|
-
|
4
|
-
if defined?(::Rails) && defined?(::Sprockets::Railtie)
|
1
|
+
if defined?(::Rails)
|
5
2
|
require 'js_routes/engine'
|
6
3
|
end
|
7
4
|
require 'js_routes/version'
|
8
|
-
require "js_routes/
|
5
|
+
require "js_routes/configuration"
|
6
|
+
require "js_routes/instance"
|
9
7
|
require 'active_support/core_ext/string/indent'
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
class Configuration
|
14
|
-
DEFAULTS = {
|
15
|
-
namespace: nil,
|
16
|
-
exclude: [],
|
17
|
-
include: //,
|
18
|
-
file: nil,
|
19
|
-
prefix: -> { Rails.application.config.relative_url_root || "" },
|
20
|
-
url_links: false,
|
21
|
-
camel_case: false,
|
22
|
-
default_url_options: {},
|
23
|
-
compact: false,
|
24
|
-
serializer: nil,
|
25
|
-
special_options_key: "_options",
|
26
|
-
application: -> { Rails.application },
|
27
|
-
module_type: 'ESM',
|
28
|
-
documentation: true,
|
29
|
-
} #:nodoc:
|
30
|
-
|
31
|
-
attr_accessor(*DEFAULTS.keys)
|
32
|
-
|
33
|
-
def initialize(attributes = nil)
|
34
|
-
assign(DEFAULTS)
|
35
|
-
return unless attributes
|
36
|
-
assign(attributes)
|
37
|
-
end
|
38
|
-
|
39
|
-
def assign(attributes)
|
40
|
-
attributes.each do |attribute, value|
|
41
|
-
value = value.call if value.is_a?(Proc)
|
42
|
-
send(:"#{attribute}=", value)
|
43
|
-
end
|
44
|
-
normalize_and_verify
|
45
|
-
self
|
46
|
-
end
|
47
|
-
|
48
|
-
def [](attribute)
|
49
|
-
send(attribute)
|
50
|
-
end
|
51
|
-
|
52
|
-
def merge(attributes)
|
53
|
-
clone.assign(attributes)
|
54
|
-
end
|
55
|
-
|
56
|
-
def to_hash
|
57
|
-
Hash[*members.zip(values).flatten(1)].symbolize_keys
|
58
|
-
end
|
59
|
-
|
60
|
-
def esm?
|
61
|
-
module_type === 'ESM'
|
62
|
-
end
|
63
|
-
|
64
|
-
def dts?
|
65
|
-
self.module_type === 'DTS'
|
66
|
-
end
|
67
|
-
|
68
|
-
def modern?
|
69
|
-
esm? || dts?
|
70
|
-
end
|
71
|
-
|
72
|
-
def require_esm
|
73
|
-
raise "ESM module type is required" unless modern?
|
74
|
-
end
|
75
|
-
|
76
|
-
def source_file
|
77
|
-
File.dirname(__FILE__) + "/" + default_file_name
|
78
|
-
end
|
79
|
-
|
80
|
-
def output_file
|
81
|
-
webpacker_dir = pathname('app', 'javascript')
|
82
|
-
sprockets_dir = pathname('app','assets','javascripts')
|
83
|
-
file_name = file || default_file_name
|
84
|
-
sprockets_file = sprockets_dir.join(file_name)
|
85
|
-
webpacker_file = webpacker_dir.join(file_name)
|
86
|
-
!Dir.exist?(webpacker_dir) && defined?(::Sprockets) ? sprockets_file : webpacker_file
|
87
|
-
end
|
88
|
-
|
89
|
-
def normalize_and_verify
|
90
|
-
normalize
|
91
|
-
verify
|
92
|
-
end
|
93
|
-
|
94
|
-
protected
|
95
|
-
|
96
|
-
def pathname(*parts)
|
97
|
-
Pathname.new(File.join(*parts))
|
98
|
-
end
|
99
|
-
|
100
|
-
def default_file_name
|
101
|
-
dts? ? "routes.d.ts" : "routes.js"
|
102
|
-
end
|
103
|
-
|
104
|
-
def normalize
|
105
|
-
self.module_type = module_type&.upcase || 'NIL'
|
106
|
-
end
|
107
|
-
|
108
|
-
def verify
|
109
|
-
if module_type != 'NIL' && namespace
|
110
|
-
raise "JsRoutes namespace option can only be used if module_type is nil"
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
9
|
+
module JsRoutes
|
114
10
|
|
115
11
|
#
|
116
12
|
# API
|
@@ -118,8 +14,7 @@ class JsRoutes
|
|
118
14
|
|
119
15
|
class << self
|
120
16
|
def setup(&block)
|
121
|
-
configuration.
|
122
|
-
configuration.normalize_and_verify
|
17
|
+
configuration.assign(&block)
|
123
18
|
end
|
124
19
|
|
125
20
|
def configuration
|
@@ -127,11 +22,11 @@ class JsRoutes
|
|
127
22
|
end
|
128
23
|
|
129
24
|
def generate(**opts)
|
130
|
-
new(opts).generate
|
25
|
+
Instance.new(opts).generate
|
131
26
|
end
|
132
27
|
|
133
|
-
def generate!(file_name=
|
134
|
-
new(file: file_name, **opts).generate!
|
28
|
+
def generate!(file_name = configuration.file, **opts)
|
29
|
+
Instance.new(file: file_name, **opts).generate!
|
135
30
|
end
|
136
31
|
|
137
32
|
def definitions(**opts)
|
@@ -147,154 +42,6 @@ class JsRoutes
|
|
147
42
|
ActiveSupport::JSON.encode(string)
|
148
43
|
end
|
149
44
|
end
|
150
|
-
|
151
|
-
attr_reader :configuration
|
152
|
-
#
|
153
|
-
# Implementation
|
154
|
-
#
|
155
|
-
|
156
|
-
def initialize(options = {})
|
157
|
-
@configuration = self.class.configuration.merge(options)
|
158
|
-
end
|
159
|
-
|
160
|
-
def generate
|
161
|
-
# Ensure routes are loaded. If they're not, load them.
|
162
|
-
if named_routes.empty? && application.respond_to?(:reload_routes!)
|
163
|
-
application.reload_routes!
|
164
|
-
end
|
165
|
-
content = File.read(@configuration.source_file)
|
166
|
-
|
167
|
-
if !@configuration.dts?
|
168
|
-
content = js_variables.inject(content) do |js, (key, value)|
|
169
|
-
js.gsub!("RubyVariables.#{key}", value.to_s) ||
|
170
|
-
raise("Missing key #{key} in JS template")
|
171
|
-
end
|
172
|
-
end
|
173
|
-
content + routes_export + prevent_types_export
|
174
|
-
end
|
175
|
-
|
176
|
-
def generate!
|
177
|
-
# Some libraries like Devise did not load their routes yet
|
178
|
-
# so we will wait until initialization process finishes
|
179
|
-
# https://github.com/railsware/js-routes/issues/7
|
180
|
-
Rails.configuration.after_initialize do
|
181
|
-
file_path = Rails.root.join(@configuration.output_file)
|
182
|
-
source_code = generate
|
183
|
-
|
184
|
-
# We don't need to rewrite file if it already exist and have same content.
|
185
|
-
# It helps asset pipeline or webpack understand that file wasn't changed.
|
186
|
-
next if File.exist?(file_path) && File.read(file_path) == source_code
|
187
|
-
|
188
|
-
File.open(file_path, 'w') do |f|
|
189
|
-
f.write source_code
|
190
|
-
end
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
protected
|
195
|
-
|
196
|
-
def js_variables
|
197
|
-
{
|
198
|
-
'GEM_VERSION' => JsRoutes::VERSION,
|
199
|
-
'ROUTES_OBJECT' => routes_object,
|
200
|
-
'RAILS_VERSION' => ActionPack.version,
|
201
|
-
'DEPRECATED_GLOBBING_BEHAVIOR' => ActionPack::VERSION::MAJOR == 4 && ActionPack::VERSION::MINOR == 0,
|
202
|
-
|
203
|
-
'APP_CLASS' => application.class.to_s,
|
204
|
-
'NAMESPACE' => json(@configuration.namespace),
|
205
|
-
'DEFAULT_URL_OPTIONS' => json(@configuration.default_url_options),
|
206
|
-
'PREFIX' => json(@configuration.prefix),
|
207
|
-
'SPECIAL_OPTIONS_KEY' => json(@configuration.special_options_key),
|
208
|
-
'SERIALIZER' => @configuration.serializer || json(nil),
|
209
|
-
'MODULE_TYPE' => json(@configuration.module_type),
|
210
|
-
'WRAPPER' => @configuration.esm? ? 'const __jsr = ' : '',
|
211
|
-
}
|
212
|
-
end
|
213
|
-
|
214
|
-
def application
|
215
|
-
@configuration.application
|
216
|
-
end
|
217
|
-
|
218
|
-
def json(string)
|
219
|
-
self.class.json(string)
|
220
|
-
end
|
221
|
-
|
222
|
-
def named_routes
|
223
|
-
application.routes.named_routes.to_a
|
224
|
-
end
|
225
|
-
|
226
|
-
def routes_object
|
227
|
-
return json({}) if @configuration.modern?
|
228
|
-
properties = routes_list.map do |comment, name, body|
|
229
|
-
"#{comment}#{name}: #{body}".indent(2)
|
230
|
-
end
|
231
|
-
"{\n" + properties.join(",\n\n") + "}\n"
|
232
|
-
end
|
233
|
-
|
234
|
-
def static_exports
|
235
|
-
[:configure, :config, :serialize].map do |name|
|
236
|
-
[
|
237
|
-
"", name,
|
238
|
-
@configuration.dts? ?
|
239
|
-
"RouterExposedMethods['#{name}']" :
|
240
|
-
"__jsr.#{name}"
|
241
|
-
]
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
def routes_export
|
246
|
-
return "" unless @configuration.modern?
|
247
|
-
[*static_exports, *routes_list].map do |comment, name, body|
|
248
|
-
"#{comment}export const #{name}#{export_separator}#{body};\n\n"
|
249
|
-
end.join
|
250
|
-
end
|
251
|
-
|
252
|
-
def prevent_types_export
|
253
|
-
return "" unless @configuration.dts?
|
254
|
-
<<-JS
|
255
|
-
// By some reason this line prevents all types in a file
|
256
|
-
// from being automatically exported
|
257
|
-
export {};
|
258
|
-
JS
|
259
|
-
end
|
260
|
-
|
261
|
-
def export_separator
|
262
|
-
@configuration.dts? ? ': ' : ' = '
|
263
|
-
end
|
264
|
-
|
265
|
-
def routes_list
|
266
|
-
named_routes.sort_by(&:first).flat_map do |_, route|
|
267
|
-
route_helpers_if_match(route) + mounted_app_routes(route)
|
268
|
-
end
|
269
|
-
end
|
270
|
-
|
271
|
-
def mounted_app_routes(route)
|
272
|
-
rails_engine_app = app_from_route(route)
|
273
|
-
if rails_engine_app.respond_to?(:superclass) &&
|
274
|
-
rails_engine_app.superclass == Rails::Engine && !route.path.anchored
|
275
|
-
rails_engine_app.routes.named_routes.flat_map do |_, engine_route|
|
276
|
-
route_helpers_if_match(engine_route, route)
|
277
|
-
end
|
278
|
-
else
|
279
|
-
[]
|
280
|
-
end
|
281
|
-
end
|
282
|
-
|
283
|
-
def app_from_route(route)
|
284
|
-
app = route.app
|
285
|
-
# rails engine in Rails 4.2 use additional
|
286
|
-
# ActionDispatch::Routing::Mapper::Constraints, which contain app
|
287
|
-
if app.respond_to?(:app) && app.respond_to?(:constraints)
|
288
|
-
app.app
|
289
|
-
else
|
290
|
-
app
|
291
|
-
end
|
292
|
-
end
|
293
|
-
|
294
|
-
def route_helpers_if_match(route, parent_route = nil)
|
295
|
-
Route.new(@configuration, route, parent_route).helpers
|
296
|
-
end
|
297
|
-
|
298
45
|
module Generators
|
299
46
|
end
|
300
47
|
end
|
data/lib/routes.d.ts
CHANGED
@@ -53,6 +53,7 @@ declare type KeywordUrlOptions = Optional<{
|
|
53
53
|
port: string | number;
|
54
54
|
anchor: string;
|
55
55
|
trailing_slash: boolean;
|
56
|
+
params: RouteParameters;
|
56
57
|
}>;
|
57
58
|
declare type RouteOptions = KeywordUrlOptions & RouteParameters;
|
58
59
|
declare type PartsTable = Record<string, {
|
@@ -66,7 +67,6 @@ declare const RubyVariables: {
|
|
66
67
|
SPECIAL_OPTIONS_KEY: string;
|
67
68
|
DEFAULT_URL_OPTIONS: RouteParameters;
|
68
69
|
SERIALIZER: Serializer;
|
69
|
-
NAMESPACE: string;
|
70
70
|
ROUTES_OBJECT: RouteHelpers;
|
71
71
|
MODULE_TYPE: ModuleType;
|
72
72
|
WRAPPER: <T>(callback: T) => T;
|
data/lib/routes.js
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
* File generated by js-routes RubyVariables.GEM_VERSION
|
3
3
|
* Based on Rails RubyVariables.RAILS_VERSION routes of RubyVariables.APP_CLASS
|
4
4
|
*/
|
5
|
-
RubyVariables.WRAPPER((
|
5
|
+
RubyVariables.WRAPPER(() => {
|
6
6
|
const hasProp = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
7
7
|
let NodeTypes;
|
8
8
|
(function (NodeTypes) {
|
@@ -15,8 +15,7 @@ RubyVariables.WRAPPER((that) => {
|
|
15
15
|
NodeTypes[NodeTypes["SLASH"] = 7] = "SLASH";
|
16
16
|
NodeTypes[NodeTypes["DOT"] = 8] = "DOT";
|
17
17
|
})(NodeTypes || (NodeTypes = {}));
|
18
|
-
const
|
19
|
-
const isBroswer = typeof window !== "undefined";
|
18
|
+
const isBrowser = typeof window !== "undefined";
|
20
19
|
const ModuleReferences = {
|
21
20
|
CJS: {
|
22
21
|
define(routes) {
|
@@ -70,11 +69,11 @@ RubyVariables.WRAPPER((that) => {
|
|
70
69
|
},
|
71
70
|
},
|
72
71
|
NIL: {
|
73
|
-
define(
|
74
|
-
|
72
|
+
define() {
|
73
|
+
// Defined using RubyVariables.WRAPPER
|
75
74
|
},
|
76
75
|
isSupported() {
|
77
|
-
return
|
76
|
+
return true;
|
78
77
|
},
|
79
78
|
},
|
80
79
|
DTS: {
|
@@ -223,12 +222,23 @@ RubyVariables.WRAPPER((that) => {
|
|
223
222
|
...options,
|
224
223
|
};
|
225
224
|
const keyword_parameters = {};
|
226
|
-
|
225
|
+
let query_parameters = {};
|
227
226
|
for (const key in options) {
|
228
227
|
if (!hasProp(options, key))
|
229
228
|
continue;
|
230
229
|
const value = options[key];
|
231
|
-
if (
|
230
|
+
if (key === "params") {
|
231
|
+
if (this.is_object(value)) {
|
232
|
+
query_parameters = {
|
233
|
+
...query_parameters,
|
234
|
+
...value,
|
235
|
+
};
|
236
|
+
}
|
237
|
+
else {
|
238
|
+
throw new Error("params value should always be an object");
|
239
|
+
}
|
240
|
+
}
|
241
|
+
else if (this.is_reserved_option(key)) {
|
232
242
|
keyword_parameters[key] = value;
|
233
243
|
}
|
234
244
|
else {
|
@@ -422,15 +432,15 @@ RubyVariables.WRAPPER((that) => {
|
|
422
432
|
}
|
423
433
|
current_host() {
|
424
434
|
var _a;
|
425
|
-
return (
|
435
|
+
return (isBrowser && ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.hostname)) || "";
|
426
436
|
}
|
427
437
|
current_protocol() {
|
428
438
|
var _a, _b;
|
429
|
-
return ((
|
439
|
+
return ((isBrowser && ((_b = (_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.protocol) === null || _b === void 0 ? void 0 : _b.replace(/:$/, ""))) || "http");
|
430
440
|
}
|
431
441
|
current_port() {
|
432
442
|
var _a;
|
433
|
-
return (
|
443
|
+
return (isBrowser && ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.port)) || "";
|
434
444
|
}
|
435
445
|
is_object(value) {
|
436
446
|
return (typeof value === "object" &&
|
@@ -445,21 +455,6 @@ RubyVariables.WRAPPER((that) => {
|
|
445
455
|
is_reserved_option(key) {
|
446
456
|
return ReservedOptions.includes(key);
|
447
457
|
}
|
448
|
-
namespace(object, namespace, routes) {
|
449
|
-
const parts = (namespace === null || namespace === void 0 ? void 0 : namespace.split(".")) || [];
|
450
|
-
if (parts.length === 0) {
|
451
|
-
return;
|
452
|
-
}
|
453
|
-
for (let index = 0; index < parts.length; index++) {
|
454
|
-
const part = parts[index];
|
455
|
-
if (index < parts.length - 1) {
|
456
|
-
object = object[part] || (object[part] = {});
|
457
|
-
}
|
458
|
-
else {
|
459
|
-
object[part] = routes;
|
460
|
-
}
|
461
|
-
}
|
462
|
-
}
|
463
458
|
configure(new_config) {
|
464
459
|
this.configuration = { ...this.configuration, ...new_config };
|
465
460
|
return this.configuration;
|
@@ -502,4 +497,4 @@ RubyVariables.WRAPPER((that) => {
|
|
502
497
|
};
|
503
498
|
Utils.define_module(RubyVariables.MODULE_TYPE, result);
|
504
499
|
return result;
|
505
|
-
})(
|
500
|
+
})();
|
data/lib/routes.ts
CHANGED
@@ -70,6 +70,7 @@ type KeywordUrlOptions = Optional<{
|
|
70
70
|
port: string | number;
|
71
71
|
anchor: string;
|
72
72
|
trailing_slash: boolean;
|
73
|
+
params: RouteParameters;
|
73
74
|
}>;
|
74
75
|
|
75
76
|
type RouteOptions = KeywordUrlOptions & RouteParameters;
|
@@ -84,7 +85,6 @@ declare const RubyVariables: {
|
|
84
85
|
SPECIAL_OPTIONS_KEY: string;
|
85
86
|
DEFAULT_URL_OPTIONS: RouteParameters;
|
86
87
|
SERIALIZER: Serializer;
|
87
|
-
NAMESPACE: string;
|
88
88
|
ROUTES_OBJECT: RouteHelpers;
|
89
89
|
MODULE_TYPE: ModuleType;
|
90
90
|
WRAPPER: <T>(callback: T) => T;
|
@@ -97,7 +97,7 @@ declare const define:
|
|
97
97
|
declare const module: { exports: any } | undefined;
|
98
98
|
|
99
99
|
RubyVariables.WRAPPER(
|
100
|
-
(
|
100
|
+
(): RouterExposedMethods => {
|
101
101
|
const hasProp = (value: unknown, key: string) =>
|
102
102
|
Object.prototype.hasOwnProperty.call(value, key);
|
103
103
|
enum NodeTypes {
|
@@ -128,8 +128,7 @@ RubyVariables.WRAPPER(
|
|
128
128
|
[T in keyof RouteNodes]: RouteNode<T>;
|
129
129
|
}[keyof RouteNodes];
|
130
130
|
|
131
|
-
const
|
132
|
-
const isBroswer = typeof window !== "undefined";
|
131
|
+
const isBrowser = typeof window !== "undefined";
|
133
132
|
type ModuleDefinition = {
|
134
133
|
define: (routes: RouterExposedMethods) => void;
|
135
134
|
isSupported: () => boolean;
|
@@ -186,11 +185,11 @@ RubyVariables.WRAPPER(
|
|
186
185
|
},
|
187
186
|
},
|
188
187
|
NIL: {
|
189
|
-
define(
|
190
|
-
|
188
|
+
define() {
|
189
|
+
// Defined using RubyVariables.WRAPPER
|
191
190
|
},
|
192
191
|
isSupported() {
|
193
|
-
return
|
192
|
+
return true;
|
194
193
|
},
|
195
194
|
},
|
196
195
|
DTS: {
|
@@ -367,11 +366,20 @@ RubyVariables.WRAPPER(
|
|
367
366
|
};
|
368
367
|
|
369
368
|
const keyword_parameters: KeywordUrlOptions = {};
|
370
|
-
|
369
|
+
let query_parameters: RouteParameters = {};
|
371
370
|
for (const key in options) {
|
372
371
|
if (!hasProp(options, key)) continue;
|
373
372
|
const value = options[key];
|
374
|
-
if (
|
373
|
+
if (key === "params") {
|
374
|
+
if (this.is_object(value)) {
|
375
|
+
query_parameters = {
|
376
|
+
...query_parameters,
|
377
|
+
...(value as RouteParameters),
|
378
|
+
};
|
379
|
+
} else {
|
380
|
+
throw new Error("params value should always be an object");
|
381
|
+
}
|
382
|
+
} else if (this.is_reserved_option(key)) {
|
375
383
|
keyword_parameters[key] = value as any;
|
376
384
|
} else {
|
377
385
|
if (
|
@@ -628,17 +636,17 @@ RubyVariables.WRAPPER(
|
|
628
636
|
}
|
629
637
|
|
630
638
|
current_host(): string {
|
631
|
-
return (
|
639
|
+
return (isBrowser && window?.location?.hostname) || "";
|
632
640
|
}
|
633
641
|
|
634
642
|
current_protocol(): string {
|
635
643
|
return (
|
636
|
-
(
|
644
|
+
(isBrowser && window?.location?.protocol?.replace(/:$/, "")) || "http"
|
637
645
|
);
|
638
646
|
}
|
639
647
|
|
640
648
|
current_port(): string {
|
641
|
-
return (
|
649
|
+
return (isBrowser && window?.location?.port) || "";
|
642
650
|
}
|
643
651
|
|
644
652
|
is_object(value: unknown): value is Record<string, unknown> {
|
@@ -660,25 +668,6 @@ RubyVariables.WRAPPER(
|
|
660
668
|
return ReservedOptions.includes(key as any);
|
661
669
|
}
|
662
670
|
|
663
|
-
namespace(
|
664
|
-
object: any,
|
665
|
-
namespace: string | null | undefined,
|
666
|
-
routes: unknown
|
667
|
-
): void {
|
668
|
-
const parts = namespace?.split(".") || [];
|
669
|
-
if (parts.length === 0) {
|
670
|
-
return;
|
671
|
-
}
|
672
|
-
for (let index = 0; index < parts.length; index++) {
|
673
|
-
const part = parts[index];
|
674
|
-
if (index < parts.length - 1) {
|
675
|
-
object = object[part] || (object[part] = {});
|
676
|
-
} else {
|
677
|
-
object[part] = routes;
|
678
|
-
}
|
679
|
-
}
|
680
|
-
}
|
681
|
-
|
682
671
|
configure(new_config: Partial<Configuration>): Configuration {
|
683
672
|
this.configuration = { ...this.configuration, ...new_config };
|
684
673
|
return this.configuration;
|
@@ -734,4 +723,4 @@ RubyVariables.WRAPPER(
|
|
734
723
|
Utils.define_module(RubyVariables.MODULE_TYPE, result);
|
735
724
|
return result;
|
736
725
|
}
|
737
|
-
)(
|
726
|
+
)();
|
@@ -7,25 +7,25 @@ describe JsRoutes, "#serialize" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should provide this method" do
|
10
|
-
|
10
|
+
expectjs("Routes.serialize({a: 1, b: [2,3], c: {d: 4, e: 5}, f: ''})").to eq(
|
11
11
|
"a=1&b%5B%5D=2&b%5B%5D=3&c%5Bd%5D=4&c%5Be%5D=5&f="
|
12
12
|
)
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should provide this method" do
|
16
|
-
|
16
|
+
expectjs("Routes.serialize({a: 1, b: [2,3], c: {d: 4, e: 5}, f: ''})").to eq(
|
17
17
|
"a=1&b%5B%5D=2&b%5B%5D=3&c%5Bd%5D=4&c%5Be%5D=5&f="
|
18
18
|
)
|
19
19
|
end
|
20
20
|
|
21
21
|
it "works with JS suckiness" do
|
22
|
-
|
22
|
+
expectjs(
|
23
23
|
[
|
24
24
|
"const query = Object.create(null);",
|
25
25
|
"query.a = 1;",
|
26
26
|
"query.b = 2;",
|
27
27
|
"Routes.serialize(query);",
|
28
28
|
].join("\n")
|
29
|
-
)
|
29
|
+
).to eq("a=1&b=2")
|
30
30
|
end
|
31
31
|
end
|
@@ -29,7 +29,7 @@ EOF
|
|
29
29
|
end
|
30
30
|
|
31
31
|
it "should working from require" do
|
32
|
-
|
32
|
+
expectjs("require(['js-routes'], function(r){ return r.inboxes_path(); })").to eq(test_routes.inboxes_path())
|
33
33
|
end
|
34
34
|
|
35
35
|
end
|
@@ -10,6 +10,6 @@ describe JsRoutes, "compatibility with CJS" do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it "should define module exports" do
|
13
|
-
|
13
|
+
expectjs("module.exports.inboxes_path()").to eq(test_routes.inboxes_path())
|
14
14
|
end
|
15
15
|
end
|
@@ -53,6 +53,7 @@ declare type KeywordUrlOptions = Optional<{
|
|
53
53
|
port: string | number;
|
54
54
|
anchor: string;
|
55
55
|
trailing_slash: boolean;
|
56
|
+
params: RouteParameters;
|
56
57
|
}>;
|
57
58
|
declare type RouteOptions = KeywordUrlOptions & RouteParameters;
|
58
59
|
declare type PartsTable = Record<string, {
|
@@ -66,7 +67,6 @@ declare const RubyVariables: {
|
|
66
67
|
SPECIAL_OPTIONS_KEY: string;
|
67
68
|
DEFAULT_URL_OPTIONS: RouteParameters;
|
68
69
|
SERIALIZER: Serializer;
|
69
|
-
NAMESPACE: string;
|
70
70
|
ROUTES_OBJECT: RouteHelpers;
|
71
71
|
MODULE_TYPE: ModuleType;
|
72
72
|
WRAPPER: <T>(callback: T) => T;
|
@@ -13,7 +13,7 @@ describe JsRoutes, "compatibility with ESM" do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
it "defines route helpers" do
|
16
|
-
|
16
|
+
expectjs("inboxes_path()").to eq(test_routes.inboxes_path())
|
17
17
|
end
|
18
18
|
|
19
19
|
it "exports route helpers" do
|
@@ -33,7 +33,7 @@ DOC
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it "defines utility methods" do
|
36
|
-
|
36
|
+
expectjs("serialize({a: 1, b: 2})").to eq({a: 1, b: 2}.to_param)
|
37
37
|
end
|
38
38
|
|
39
39
|
describe "compiled javascript asset" do
|
@@ -36,7 +36,7 @@ describe JsRoutes, "compatibility with NIL (legacy browser)" do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
it "should be possible" do
|
39
|
-
|
39
|
+
expectjs("r.inboxes_path()").to eq(test_routes.inboxes_path())
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -45,12 +45,13 @@ describe JsRoutes, "compatibility with NIL (legacy browser)" do
|
|
45
45
|
let(:_presetup) { "" }
|
46
46
|
before do
|
47
47
|
evaljs("var window = this;")
|
48
|
+
evaljs("window.PHM = {}")
|
48
49
|
evaljs(_presetup)
|
49
50
|
evaljs(generated_js)
|
50
51
|
end
|
51
52
|
it "should use this namespace for routing" do
|
52
|
-
|
53
|
-
|
53
|
+
expectjs("window.Routes").to be_nil
|
54
|
+
expectjs("window.PHM.inboxes_path").not_to be_nil
|
54
55
|
end
|
55
56
|
|
56
57
|
describe "is nested" do
|
@@ -59,7 +60,7 @@ describe JsRoutes, "compatibility with NIL (legacy browser)" do
|
|
59
60
|
let(:_options) { {namespace: "PHM.Routes"} }
|
60
61
|
|
61
62
|
it "should use this namespace for routing" do
|
62
|
-
|
63
|
+
expectjs("PHM.Routes.inboxes_path").not_to be_nil
|
63
64
|
end
|
64
65
|
end
|
65
66
|
|
@@ -67,7 +68,7 @@ describe JsRoutes, "compatibility with NIL (legacy browser)" do
|
|
67
68
|
let(:_options) { {namespace: "PHM.Routes"} }
|
68
69
|
|
69
70
|
it "should initialize namespace" do
|
70
|
-
|
71
|
+
expectjs("window.PHM.Routes.inboxes_path").not_to be_nil
|
71
72
|
end
|
72
73
|
end
|
73
74
|
|
@@ -76,8 +77,8 @@ describe JsRoutes, "compatibility with NIL (legacy browser)" do
|
|
76
77
|
let(:_options) { {namespace: "PHM.Routes"} }
|
77
78
|
|
78
79
|
it "should not overwrite existing parts" do
|
79
|
-
|
80
|
-
|
80
|
+
expectjs("window.PHM.Utils").not_to be_nil
|
81
|
+
expectjs("window.PHM.Routes.inboxes_path").not_to be_nil
|
81
82
|
end
|
82
83
|
end
|
83
84
|
end
|