js-routes 2.1.1 → 2.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/Readme.md +87 -49
- data/lib/js_routes/configuration.rb +111 -0
- data/lib/js_routes/engine.rb +1 -1
- data/lib/js_routes/generators/middleware.rb +58 -0
- data/lib/js_routes/generators/webpacker.rb +1 -1
- data/lib/js_routes/instance.rb +154 -0
- data/lib/js_routes/middleware.rb +36 -0
- data/lib/js_routes/route.rb +172 -0
- data/lib/js_routes/version.rb +2 -2
- data/lib/js_routes.rb +11 -421
- data/lib/routes.js +10 -7
- data/lib/routes.ts +13 -8
- data/spec/js_routes/module_types/amd_spec.rb +6 -5
- data/spec/js_routes/module_types/nil_spec.rb +86 -0
- data/spec/js_routes/module_types/umd_spec.rb +1 -1
- data/spec/js_routes/options_spec.rb +33 -51
- data/spec/spec_helper.rb +1 -2
- data/spec/support/routes.rb +1 -1
- metadata +8 -2
data/lib/routes.ts
CHANGED
@@ -129,6 +129,7 @@ RubyVariables.WRAPPER(
|
|
129
129
|
}[keyof RouteNodes];
|
130
130
|
|
131
131
|
const Root = that;
|
132
|
+
const isBroswer = typeof window !== "undefined";
|
132
133
|
type ModuleDefinition = {
|
133
134
|
define: (routes: RouterExposedMethods) => void;
|
134
135
|
isSupported: () => boolean;
|
@@ -189,7 +190,7 @@ RubyVariables.WRAPPER(
|
|
189
190
|
Utils.namespace(Root, RubyVariables.NAMESPACE, routes);
|
190
191
|
},
|
191
192
|
isSupported() {
|
192
|
-
return !!Root;
|
193
|
+
return !RubyVariables.NAMESPACE || !!Root;
|
193
194
|
},
|
194
195
|
},
|
195
196
|
DTS: {
|
@@ -348,7 +349,9 @@ RubyVariables.WRAPPER(
|
|
348
349
|
throw new Error("Too many parameters provided for path");
|
349
350
|
}
|
350
351
|
let use_all_parts = args.length > required_params.length;
|
351
|
-
const parts_options: RouteParameters = {
|
352
|
+
const parts_options: RouteParameters = {
|
353
|
+
...this.configuration.default_url_options,
|
354
|
+
};
|
352
355
|
for (const key in options) {
|
353
356
|
const value = options[key];
|
354
357
|
if (!hasProp(options, key)) continue;
|
@@ -625,15 +628,17 @@ RubyVariables.WRAPPER(
|
|
625
628
|
}
|
626
629
|
|
627
630
|
current_host(): string {
|
628
|
-
return window?.location?.hostname || "";
|
631
|
+
return (isBroswer && window?.location?.hostname) || "";
|
629
632
|
}
|
630
633
|
|
631
634
|
current_protocol(): string {
|
632
|
-
return
|
635
|
+
return (
|
636
|
+
(isBroswer && window?.location?.protocol?.replace(/:$/, "")) || "http"
|
637
|
+
);
|
633
638
|
}
|
634
639
|
|
635
640
|
current_port(): string {
|
636
|
-
return window?.location?.port || "";
|
641
|
+
return (isBroswer && window?.location?.port) || "";
|
637
642
|
}
|
638
643
|
|
639
644
|
is_object(value: unknown): value is Record<string, unknown> {
|
@@ -659,17 +664,17 @@ RubyVariables.WRAPPER(
|
|
659
664
|
object: any,
|
660
665
|
namespace: string | null | undefined,
|
661
666
|
routes: unknown
|
662
|
-
):
|
667
|
+
): void {
|
663
668
|
const parts = namespace?.split(".") || [];
|
664
669
|
if (parts.length === 0) {
|
665
|
-
return
|
670
|
+
return;
|
666
671
|
}
|
667
672
|
for (let index = 0; index < parts.length; index++) {
|
668
673
|
const part = parts[index];
|
669
674
|
if (index < parts.length - 1) {
|
670
675
|
object = object[part] || (object[part] = {});
|
671
676
|
} else {
|
672
|
-
|
677
|
+
object[part] = routes;
|
673
678
|
}
|
674
679
|
}
|
675
680
|
}
|
@@ -3,11 +3,12 @@ require "spec_helper"
|
|
3
3
|
describe JsRoutes, "compatibility with AMD/require.js" do
|
4
4
|
|
5
5
|
before(:each) do
|
6
|
-
evaljs("
|
7
|
-
evaljs("
|
8
|
-
evaljs("
|
6
|
+
evaljs("var global = this;", {force: true})
|
7
|
+
evaljs("global.GlobalCheck = {};")
|
8
|
+
evaljs("global.define = function (requirs, callback) { global.GlobalCheck['js-routes'] = callback.call(this); return global.GlobalCheck['js-routes']; };")
|
9
|
+
evaljs("global.define.amd = { jQuery: true };")
|
9
10
|
strRequire =<<EOF
|
10
|
-
|
11
|
+
global.require = function (r, callback) {
|
11
12
|
var allArgs, i;
|
12
13
|
|
13
14
|
allArgs = (function() {
|
@@ -15,7 +16,7 @@ describe JsRoutes, "compatibility with AMD/require.js" do
|
|
15
16
|
_results = [];
|
16
17
|
for (_i = 0, _len = r.length; _i < _len; _i++) {
|
17
18
|
i = r[_i];
|
18
|
-
_results.push(
|
19
|
+
_results.push(global.GlobalCheck[i]);
|
19
20
|
}
|
20
21
|
return _results;
|
21
22
|
})();
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe JsRoutes, "compatibility with NIL (legacy browser)" do
|
4
|
+
let(:generated_js) do
|
5
|
+
JsRoutes.generate(
|
6
|
+
module_type: nil,
|
7
|
+
include: /book|inboxes|inbox_message/,
|
8
|
+
**_options
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:_options) { {} }
|
13
|
+
describe "generated js" do
|
14
|
+
subject do
|
15
|
+
generated_js
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should call route function for each route" do
|
19
|
+
is_expected.to include("inboxes_path: __jsr.r(")
|
20
|
+
end
|
21
|
+
it "should have correct function without arguments signature" do
|
22
|
+
is_expected.to include('inboxes_path: __jsr.r({"format":{}}')
|
23
|
+
end
|
24
|
+
it "should have correct function with arguments signature" do
|
25
|
+
is_expected.to include('inbox_message_path: __jsr.r({"inbox_id":{"r":true},"id":{"r":true},"format":{}}')
|
26
|
+
end
|
27
|
+
it "should have correct function signature with unordered hash" do
|
28
|
+
is_expected.to include('inbox_message_attachment_path: __jsr.r({"inbox_id":{"r":true},"message_id":{"r":true},"id":{"r":true},"format":{}}')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "inline generation" do
|
33
|
+
let(:_options) { {namespace: nil} }
|
34
|
+
before do
|
35
|
+
evaljs("const r = #{generated_js}")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should be possible" do
|
39
|
+
expect(evaljs("r.inboxes_path()")).to eq(test_routes.inboxes_path())
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "namespace option" do
|
44
|
+
let(:_options) { {namespace: "PHM"} }
|
45
|
+
let(:_presetup) { "" }
|
46
|
+
before do
|
47
|
+
evaljs("var window = this;")
|
48
|
+
evaljs(_presetup)
|
49
|
+
evaljs(generated_js)
|
50
|
+
end
|
51
|
+
it "should use this namespace for routing" do
|
52
|
+
expect(evaljs("window.Routes")).to be_nil
|
53
|
+
expect(evaljs("window.PHM.inboxes_path")).not_to be_nil
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "is nested" do
|
57
|
+
context "and defined on client" do
|
58
|
+
let(:_presetup) { "window.PHM = {}" }
|
59
|
+
let(:_options) { {namespace: "PHM.Routes"} }
|
60
|
+
|
61
|
+
it "should use this namespace for routing" do
|
62
|
+
expect(evaljs("PHM.Routes.inboxes_path")).not_to be_nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "but undefined on client" do
|
67
|
+
let(:_options) { {namespace: "PHM.Routes"} }
|
68
|
+
|
69
|
+
it "should initialize namespace" do
|
70
|
+
expect(evaljs("window.PHM.Routes.inboxes_path")).not_to be_nil
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "and some parts are defined" do
|
75
|
+
let(:_presetup) { "window.PHM = { Utils: {} };" }
|
76
|
+
let(:_options) { {namespace: "PHM.Routes"} }
|
77
|
+
|
78
|
+
it "should not overwrite existing parts" do
|
79
|
+
expect(evaljs("window.PHM.Utils")).not_to be_nil
|
80
|
+
expect(evaljs("window.PHM.Routes.inboxes_path")).not_to be_nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
@@ -188,55 +188,19 @@ describe JsRoutes, "options" do
|
|
188
188
|
expect(evaljs("Routes.no_format_path({format: 'json'})")).to eq(test_routes.no_format_path(format: 'json'))
|
189
189
|
end
|
190
190
|
|
191
|
-
describe "namespace option" do
|
192
|
-
let(:_options) { {:namespace => "PHM"} }
|
193
|
-
it "should use this namespace for routing" do
|
194
|
-
expect(evaljs("window.Routes")).to be_nil
|
195
|
-
expect(evaljs("PHM.inbox_path")).not_to be_nil
|
196
|
-
end
|
197
|
-
|
198
|
-
context "is nil" do
|
199
|
-
let(:_options) { {:namespace => nil, include: /^inbox$/} }
|
200
|
-
it "should use this namespace for routing" do
|
201
|
-
evaljs("window.zz = #{generated_js}")
|
202
|
-
expect(evaljs("window.zz.inbox_path")).not_to be_nil
|
203
|
-
end
|
204
|
-
|
205
|
-
end
|
206
|
-
|
207
|
-
describe "is nested" do
|
208
|
-
context "and defined on client" do
|
209
|
-
let(:_presetup) { "window.PHM = {}" }
|
210
|
-
let(:_options) { {:namespace => "PHM.Routes"} }
|
211
|
-
it "should use this namespace for routing" do
|
212
|
-
expect(evaljs("PHM.Routes.inbox_path")).not_to be_nil
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
context "but undefined on client" do
|
217
|
-
let(:_options) { {:namespace => "PHM.Routes"} }
|
218
|
-
it "should initialize namespace" do
|
219
|
-
expect(evaljs("window.PHM.Routes.inbox_path")).not_to be_nil
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
context "and some parts are defined" do
|
224
|
-
let(:_presetup) { "window.PHM = { Utils: {} };" }
|
225
|
-
let(:_options) { {:namespace => "PHM.Routes"} }
|
226
|
-
it "should not overwrite existing parts" do
|
227
|
-
expect(evaljs("window.PHM.Utils")).not_to be_nil
|
228
|
-
expect(evaljs("window.PHM.Routes.inbox_path")).not_to be_nil
|
229
|
-
end
|
230
|
-
end
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
191
|
describe "default_url_options" do
|
235
192
|
context "with optional route parts" do
|
236
|
-
context "provided" do
|
193
|
+
context "provided by the default_url_options" do
|
237
194
|
let(:_options) { { :default_url_options => { :optional_id => "12", :format => "json" } } }
|
238
|
-
it "should use this
|
239
|
-
expect(evaljs("Routes.things_path()")).to eq(test_routes.things_path)
|
195
|
+
it "should use this options to fill optional parameters" do
|
196
|
+
expect(evaljs("Routes.things_path()")).to eq(test_routes.things_path(12))
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
context "provided inline by the method parameters" do
|
201
|
+
let(:options) { { :default_url_options => { :optional_id => "12" } } }
|
202
|
+
it "should overwrite the default_url_options" do
|
203
|
+
expect(evaljs("Routes.things_path({ optional_id: 34 })")).to eq(test_routes.things_path(optional_id: 34))
|
240
204
|
end
|
241
205
|
end
|
242
206
|
|
@@ -249,12 +213,25 @@ describe JsRoutes, "options" do
|
|
249
213
|
end
|
250
214
|
|
251
215
|
context "with required route parts" do
|
252
|
-
let(:_options) { {:default_url_options => {:inbox_id => "12"}} }
|
253
|
-
it "should use this
|
216
|
+
let(:_options) { { :default_url_options => { :inbox_id => "12" } } }
|
217
|
+
it "should use this options to fill optional parameters" do
|
254
218
|
expect(evaljs("Routes.inbox_messages_path()")).to eq(test_routes.inbox_messages_path)
|
255
219
|
end
|
256
220
|
end
|
257
221
|
|
222
|
+
context "with optional and required route parts" do
|
223
|
+
let(:_options) { {:default_url_options => { :optional_id => "12" } } }
|
224
|
+
it "should use this options to fill the optional parameters" do
|
225
|
+
expect(evaljs("Routes.thing_path(1)")).to eq test_routes.thing_path(1, { optional_id: "12" })
|
226
|
+
end
|
227
|
+
|
228
|
+
context "when passing options that do not have defaults" do
|
229
|
+
it "should use this options to fill the optional parameters" do
|
230
|
+
expect(evaljs("Routes.thing_path(1, { format: 'json' })")).to eq test_routes.thing_path(1, { optional_id: "12", format: "json" } ) # test_routes.thing_path needs optional_id here to generate the correct route. Not sure why.
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
258
235
|
context "when overwritten on JS level" do
|
259
236
|
let(:_options) { { :default_url_options => { :format => "json" } } }
|
260
237
|
it "uses JS defined value" do
|
@@ -421,8 +398,14 @@ describe JsRoutes, "options" do
|
|
421
398
|
host
|
422
399
|
end
|
423
400
|
|
424
|
-
|
425
|
-
|
401
|
+
let(:_presetup) do
|
402
|
+
window = {location: {
|
403
|
+
protocol: current_protocol,
|
404
|
+
hostname: current_hostname,
|
405
|
+
port: current_port,
|
406
|
+
host: current_host,
|
407
|
+
}}
|
408
|
+
"const window = #{ActiveSupport::JSON.encode(window)}"
|
426
409
|
end
|
427
410
|
|
428
411
|
context "without specifying a default host" do
|
@@ -434,7 +417,6 @@ describe JsRoutes, "options" do
|
|
434
417
|
expect(evaljs("Routes.inbox_url(1)")).to eq("http://current.example.com#{test_routes.inbox_path(1)}")
|
435
418
|
expect(evaljs("Routes.inbox_url(1, { test_key: \"test_val\" })")).to eq("http://current.example.com#{test_routes.inbox_path(1, :test_key => "test_val")}")
|
436
419
|
expect(evaljs("Routes.new_session_url()")).to eq("https://current.example.com#{test_routes.new_session_path}")
|
437
|
-
|
438
420
|
end
|
439
421
|
|
440
422
|
it "doesn't use current when specified in the route" do
|
data/spec/spec_helper.rb
CHANGED
@@ -108,11 +108,10 @@ RSpec.configure do |config|
|
|
108
108
|
end
|
109
109
|
|
110
110
|
config.before :each do
|
111
|
-
evaljs("var window = this;", {force: true})
|
112
|
-
|
113
111
|
log = proc do |*values|
|
114
112
|
puts values.map(&:inspect).join(", ")
|
115
113
|
end
|
114
|
+
|
116
115
|
if defined?(JRUBY_VERSION)
|
117
116
|
jscontext[:"console.log"] = lambda do |context, *values|
|
118
117
|
log(*values)
|
data/spec/support/routes.rb
CHANGED
@@ -62,7 +62,7 @@ def draw_routes
|
|
62
62
|
|
63
63
|
resources :portals, :port => 8080, only: [:index]
|
64
64
|
|
65
|
-
get '/with_defaults' => 'foo#foo', defaults: { bar: 'tested', format: :json }, format:
|
65
|
+
get '/with_defaults' => 'foo#foo', defaults: { bar: 'tested', format: :json }, format: true
|
66
66
|
|
67
67
|
namespace :api, format: true, defaults: {format: 'json'} do
|
68
68
|
get "/purchases" => "purchases#index"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: js-routes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bogdan Gusiev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -170,8 +170,13 @@ files:
|
|
170
170
|
- js-routes.gemspec
|
171
171
|
- lib/js-routes.rb
|
172
172
|
- lib/js_routes.rb
|
173
|
+
- lib/js_routes/configuration.rb
|
173
174
|
- lib/js_routes/engine.rb
|
175
|
+
- lib/js_routes/generators/middleware.rb
|
174
176
|
- lib/js_routes/generators/webpacker.rb
|
177
|
+
- lib/js_routes/instance.rb
|
178
|
+
- lib/js_routes/middleware.rb
|
179
|
+
- lib/js_routes/route.rb
|
175
180
|
- lib/js_routes/version.rb
|
176
181
|
- lib/routes.d.ts
|
177
182
|
- lib/routes.js
|
@@ -191,6 +196,7 @@ files:
|
|
191
196
|
- spec/js_routes/module_types/dts/test.spec.ts
|
192
197
|
- spec/js_routes/module_types/dts_spec.rb
|
193
198
|
- spec/js_routes/module_types/esm_spec.rb
|
199
|
+
- spec/js_routes/module_types/nil_spec.rb
|
194
200
|
- spec/js_routes/module_types/umd_spec.rb
|
195
201
|
- spec/js_routes/options_spec.rb
|
196
202
|
- spec/js_routes/rails_routes_compatibility_spec.rb
|