js-routes 1.4.9 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.eslintrc.js +15 -0
- data/.gitignore +4 -0
- data/.nvmrc +1 -0
- data/.travis.yml +2 -1
- data/CHANGELOG.md +29 -0
- data/Readme.md +189 -65
- data/VERSION_2_UPGRADE.md +61 -0
- data/js-routes.gemspec +7 -4
- data/lib/js_routes.rb +109 -63
- data/lib/js_routes/engine.rb +0 -1
- data/lib/js_routes/version.rb +1 -1
- data/lib/routes.d.ts +64 -0
- data/lib/routes.js +479 -518
- data/lib/routes.js.map +1 -0
- data/lib/routes.ts +680 -0
- data/package.json +36 -0
- data/spec/dummy/app/assets/config/manifest.js +2 -0
- data/spec/js_routes/default_serializer_spec.rb +8 -3
- data/spec/js_routes/{amd_compatibility_spec.rb → module_types/amd_spec.rb} +1 -9
- data/spec/js_routes/module_types/cjs_spec.rb +15 -0
- data/spec/js_routes/module_types/esm_spec.rb +45 -0
- data/spec/js_routes/{generated_javascript_spec.rb → module_types/umd_spec.rb} +32 -26
- data/spec/js_routes/options_spec.rb +19 -6
- data/spec/js_routes/rails_routes_compatibility_spec.rb +40 -21
- data/spec/js_routes/zzz_last_post_rails_init_spec.rb +2 -2
- data/spec/spec_helper.rb +25 -17
- data/tsconfig.json +32 -0
- data/yarn.lock +2145 -0
- metadata +30 -20
- data/lib/routes.js.coffee +0 -411
data/package.json
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
{
|
2
|
+
"name": "js-routes",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"main": "index.js",
|
5
|
+
"repository": "git@github.com:railsware/js-routes.git",
|
6
|
+
"author": "Bogdan Gusiev <agresso@gmail.com>, Alexey Vasiliev <https://leopard.in.ua> ",
|
7
|
+
"license": "MIT",
|
8
|
+
"private": false,
|
9
|
+
"devDependencies": {
|
10
|
+
"typescript": "^4.1.2"
|
11
|
+
},
|
12
|
+
"dependencies": {
|
13
|
+
"@typescript-eslint/eslint-plugin": "^4.9.0",
|
14
|
+
"@typescript-eslint/parser": "^4.9.0",
|
15
|
+
"eslint": "^7.14.0",
|
16
|
+
"eslint-config-prettier": "^6.15.0",
|
17
|
+
"eslint-plugin-import": "^2.22.1",
|
18
|
+
"husky": "^4.3.0",
|
19
|
+
"lint-staged": "^10.5.2",
|
20
|
+
"pinst": "^2.1.1",
|
21
|
+
"prettier": "^2.2.1"
|
22
|
+
},
|
23
|
+
"scripts": {
|
24
|
+
"lint:fix": "yarn eslint --fix && yarn prettier --write lib/routes.ts",
|
25
|
+
"postinstall": "yarn husky-upgrade"
|
26
|
+
},
|
27
|
+
"husky": {
|
28
|
+
"hooks": {
|
29
|
+
"pre-commit": "yarn lint:fix"
|
30
|
+
}
|
31
|
+
},
|
32
|
+
"lint-staged": {
|
33
|
+
"*.ts": ["yarn lint:fix" ]
|
34
|
+
}
|
35
|
+
|
36
|
+
}
|
@@ -1,15 +1,20 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
describe JsRoutes, "#
|
3
|
+
describe JsRoutes, "#serialize" do
|
4
4
|
|
5
5
|
before(:each) do
|
6
|
-
evaljs(JsRoutes.generate({}))
|
6
|
+
evaljs(JsRoutes.generate({module_type: nil}))
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should provide this method" do
|
10
|
-
expect(evaljs("Routes.
|
10
|
+
expect(evaljs("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
|
+
it "should provide this method" do
|
16
|
+
expect(evaljs("Routes.serialize({a: 1, b: [2,3], c: {d: 4, e: 5}, f: ''})")).to eq(
|
17
|
+
"a=1&b%5B%5D=2&b%5B%5D=3&c%5Bd%5D=4&c%5Be%5D=5&f="
|
18
|
+
)
|
19
|
+
end
|
15
20
|
end
|
@@ -24,15 +24,7 @@ describe JsRoutes, "compatibility with AMD/require.js" do
|
|
24
24
|
};
|
25
25
|
EOF
|
26
26
|
evaljs(strRequire)
|
27
|
-
evaljs(JsRoutes.generate({}))
|
28
|
-
end
|
29
|
-
|
30
|
-
it "should working from global scope" do
|
31
|
-
expect(evaljs("Routes.inboxes_path()")).to eq(test_routes.inboxes_path())
|
32
|
-
end
|
33
|
-
|
34
|
-
it "should working from define function" do
|
35
|
-
expect(evaljs("Routes.inboxes_path()")).to eq(evaljs("GlobalCheck['js-routes'].inboxes_path()"))
|
27
|
+
evaljs(JsRoutes.generate({module_type: 'AMD'}))
|
36
28
|
end
|
37
29
|
|
38
30
|
it "should working from require" do
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe JsRoutes, "compatibility with CJS" do
|
4
|
+
before(:each) do
|
5
|
+
evaljs("module = { exports: null }")
|
6
|
+
evaljs(JsRoutes.generate(
|
7
|
+
module_type: 'CJS',
|
8
|
+
include: /^inboxes/
|
9
|
+
))
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should define module exports" do
|
13
|
+
expect(evaljs("module.exports.inboxes_path()")).to eq(test_routes.inboxes_path())
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "active_support/core_ext/string/strip"
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe JsRoutes, "compatibility with ESM" do
|
5
|
+
|
6
|
+
let(:generated_js) {
|
7
|
+
JsRoutes.generate(module_type: 'ESM')
|
8
|
+
}
|
9
|
+
|
10
|
+
before(:each) do
|
11
|
+
# export keyword is not supported by a simulated js environment
|
12
|
+
evaljs(generated_js.gsub("export const ", "const "))
|
13
|
+
end
|
14
|
+
|
15
|
+
it "defines route helpers" do
|
16
|
+
expect(evaljs("inboxes_path()")).to eq(test_routes.inboxes_path())
|
17
|
+
end
|
18
|
+
|
19
|
+
it "exports route helpers" do
|
20
|
+
expect(generated_js).to include(<<-DOC.rstrip)
|
21
|
+
/**
|
22
|
+
* Generates rails route to
|
23
|
+
* /inboxes(.:format)
|
24
|
+
* @param {object | undefined} options
|
25
|
+
* @returns {string} route path
|
26
|
+
*/
|
27
|
+
export const inboxes_path = __jsr.r
|
28
|
+
DOC
|
29
|
+
end
|
30
|
+
|
31
|
+
it "exports utility methods" do
|
32
|
+
expect(generated_js).to include("export const serialize = ")
|
33
|
+
end
|
34
|
+
|
35
|
+
it "defines utility methods" do
|
36
|
+
expect(evaljs("serialize({a: 1, b: 2})")).to eq({a: 1, b: 2}.to_param)
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "compiled javascript asset" do
|
40
|
+
subject { ERB.new(File.read("app/assets/javascripts/js-routes.js.erb")).result(binding) }
|
41
|
+
it "should have js routes code" do
|
42
|
+
is_expected.to include("export const inbox_message_path = __jsr.r(")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -1,14 +1,15 @@
|
|
1
|
-
require
|
1
|
+
require "active_support/core_ext/string/strip"
|
2
2
|
require "fileutils"
|
3
|
-
|
3
|
+
require 'spec_helper'
|
4
4
|
|
5
5
|
describe JsRoutes do
|
6
|
-
before(:each) do
|
7
|
-
evaljs(JsRoutes.generate)
|
8
|
-
end
|
9
|
-
|
10
6
|
describe "generated js" do
|
11
|
-
subject
|
7
|
+
subject do
|
8
|
+
JsRoutes.generate(
|
9
|
+
module_type: 'UMD',
|
10
|
+
include: /book|inboxes|inbox_message/,
|
11
|
+
)
|
12
|
+
end
|
12
13
|
|
13
14
|
it "should include a comment in the header" do
|
14
15
|
app_class = "App"
|
@@ -18,23 +19,41 @@ describe JsRoutes do
|
|
18
19
|
end
|
19
20
|
|
20
21
|
it "should call route function for each route" do
|
21
|
-
is_expected.to include("inboxes_path:
|
22
|
+
is_expected.to include("inboxes_path: __jsr.r(")
|
22
23
|
end
|
23
24
|
it "should have correct function without arguments signature" do
|
24
|
-
is_expected.to include(
|
25
|
+
is_expected.to include('inboxes_path: __jsr.r({"format":{}}')
|
25
26
|
end
|
26
27
|
it "should have correct function with arguments signature" do
|
27
|
-
is_expected.to include(
|
28
|
+
is_expected.to include('inbox_message_path: __jsr.r({"inbox_id":{"r":true},"id":{"r":true},"format":{}}')
|
28
29
|
end
|
29
30
|
it "should have correct function signature with unordered hash" do
|
30
|
-
is_expected.to include(
|
31
|
+
is_expected.to include('inbox_message_attachment_path: __jsr.r({"inbox_id":{"r":true},"message_id":{"r":true},"id":{"r":true},"format":{}}')
|
31
32
|
end
|
32
33
|
|
33
34
|
it "should have correct function comment with options argument" do
|
34
|
-
is_expected.to include(
|
35
|
+
is_expected.to include(<<-DOC.rstrip)
|
36
|
+
/**
|
37
|
+
* Generates rails route to
|
38
|
+
* /inboxes(.:format)
|
39
|
+
* @param {object | undefined} options
|
40
|
+
* @returns {string} route path
|
41
|
+
*/
|
42
|
+
inboxes_path: __jsr.r
|
43
|
+
DOC
|
35
44
|
end
|
36
45
|
it "should have correct function comment with arguments" do
|
37
|
-
is_expected.to include(
|
46
|
+
is_expected.to include(<<-DOC.rstrip)
|
47
|
+
/**
|
48
|
+
* Generates rails route to
|
49
|
+
* /inboxes/:inbox_id/messages/:message_id/attachments/new(.:format)
|
50
|
+
* @param {any} inbox_id
|
51
|
+
* @param {any} message_id
|
52
|
+
* @param {object | undefined} options
|
53
|
+
* @returns {string} route path
|
54
|
+
*/
|
55
|
+
new_inbox_message_attachment_path: __jsr.r
|
56
|
+
DOC
|
38
57
|
end
|
39
58
|
|
40
59
|
it "routes should be sorted in alphabetical order" do
|
@@ -60,20 +79,7 @@ describe JsRoutes do
|
|
60
79
|
end
|
61
80
|
|
62
81
|
it "should not generate file before initialization" do
|
63
|
-
# This method is alread fixed in Rails master
|
64
|
-
# But in 3.2 stable we need to hack it like this
|
65
|
-
if Rails.application.instance_variable_get("@initialized")
|
66
|
-
pending
|
67
|
-
end
|
68
82
|
expect(File.exists?(name)).to be_falsey
|
69
83
|
end
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
|
-
describe "compiled javascript asset" do
|
74
|
-
subject { ERB.new(File.read("app/assets/javascripts/js-routes.js.erb")).result(binding) }
|
75
|
-
it "should have js routes code" do
|
76
|
-
is_expected.to include("inbox_message_path: Utils.route([[\"inbox_id\",true],[\"id\",true],[\"format\",false]]")
|
77
|
-
end
|
78
84
|
end
|
79
85
|
end
|
@@ -2,10 +2,14 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe JsRoutes, "options" do
|
4
4
|
|
5
|
+
let(:generated_js) do
|
6
|
+
JsRoutes.generate({module_type: nil, **_options})
|
7
|
+
end
|
8
|
+
|
5
9
|
before(:each) do
|
6
10
|
evaljs(_presetup) if _presetup
|
7
11
|
with_warnings(_warnings) do
|
8
|
-
evaljs(
|
12
|
+
evaljs(generated_js)
|
9
13
|
App.routes.default_url_options = _options[:default_url_options] || {}
|
10
14
|
end
|
11
15
|
end
|
@@ -37,9 +41,10 @@ describe JsRoutes, "options" do
|
|
37
41
|
let(:_presetup){ %q(var myCustomSerializer = 1) }
|
38
42
|
let(:_options) { {:serializer => "myCustomSerializer"} }
|
39
43
|
|
40
|
-
it "should
|
41
|
-
|
42
|
-
|
44
|
+
it "should throw error" do
|
45
|
+
expect {
|
46
|
+
evaljs(%q(Routes.inboxes_path({a: 1})))
|
47
|
+
}.to raise_error(js_error_class)
|
43
48
|
end
|
44
49
|
end
|
45
50
|
|
@@ -177,8 +182,7 @@ describe JsRoutes, "options" do
|
|
177
182
|
context "is nil" do
|
178
183
|
let(:_options) { {:namespace => nil} }
|
179
184
|
it "should use this namespace for routing" do
|
180
|
-
evaljs("window.zz = #{JsRoutes.generate(namespace: nil)}")
|
181
|
-
expect(evaljs("window.Routes")).to be_nil
|
185
|
+
evaljs("window.zz = #{JsRoutes.generate(module_type: nil, namespace: nil)}")
|
182
186
|
expect(evaljs("window.zz.inbox_path")).not_to be_nil
|
183
187
|
end
|
184
188
|
|
@@ -491,4 +495,13 @@ describe JsRoutes, "options" do
|
|
491
495
|
expect(evaljs("Routes.posts_path()")).not_to be_nil
|
492
496
|
end
|
493
497
|
end
|
498
|
+
|
499
|
+
describe "documentation option" do
|
500
|
+
let(:_options) { {documentation: false} }
|
501
|
+
|
502
|
+
it "disables documentation generation" do
|
503
|
+
expect(generated_js).not_to include("@param")
|
504
|
+
expect(generated_js).not_to include("@returns")
|
505
|
+
end
|
506
|
+
end
|
494
507
|
end
|
@@ -3,7 +3,7 @@ require "spec_helper"
|
|
3
3
|
describe JsRoutes, "compatibility with Rails" do
|
4
4
|
|
5
5
|
before(:each) do
|
6
|
-
evaljs(JsRoutes.generate({}))
|
6
|
+
evaljs(JsRoutes.generate({module_type: nil}))
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should generate collection routing" do
|
@@ -16,13 +16,16 @@ describe JsRoutes, "compatibility with Rails" do
|
|
16
16
|
|
17
17
|
it "should raise error if required argument is not passed", :aggregate_failures do
|
18
18
|
expect { evaljs("Routes.thing_path()") }
|
19
|
-
.to raise_error(/Route
|
19
|
+
.to raise_error(/Route missing required keys: id/)
|
20
20
|
expect { evaljs("Routes.search_path()") }
|
21
|
-
.to raise_error(/Route
|
21
|
+
.to raise_error(/Route missing required keys: q/)
|
22
22
|
expect { evaljs("Routes.book_path()") }
|
23
|
-
.to raise_error(/Route
|
23
|
+
.to raise_error(/Route missing required keys: section, title/)
|
24
24
|
expect { evaljs("Routes.book_title_path()") }
|
25
|
-
.to raise_error(/Route
|
25
|
+
.to raise_error(/Route missing required keys: title/)
|
26
|
+
|
27
|
+
expect( evaljs("try {Routes.thing_path()} catch (e) { e.name }") ).to eq('ParametersMissing')
|
28
|
+
expect( evaljs("try {Routes.thing_path()} catch (e) { e.keys }") ).to eq(['id'])
|
26
29
|
end
|
27
30
|
|
28
31
|
it "should produce error stacktraces including function names" do
|
@@ -110,6 +113,7 @@ describe JsRoutes, "compatibility with Rails" do
|
|
110
113
|
|
111
114
|
it "doesn't apply defaults to path" do
|
112
115
|
expect(evaljs("Routes.with_defaults_path()")).to eq(test_routes.with_defaults_path)
|
116
|
+
expect(evaljs("Routes.with_defaults_path({format: 'json'})")).to eq(test_routes.with_defaults_path(format: 'json'))
|
113
117
|
end
|
114
118
|
end
|
115
119
|
|
@@ -235,7 +239,7 @@ describe JsRoutes, "compatibility with Rails" do
|
|
235
239
|
|
236
240
|
it "should raise error when passing non-full list of arguments and some query params" do
|
237
241
|
expect { evaljs("Routes.thing_path(5, {q: 'hello'})") }
|
238
|
-
.to raise_error(/Route
|
242
|
+
.to raise_error(/Route missing required keys: id/)
|
239
243
|
end
|
240
244
|
|
241
245
|
it "should treat null as non-given optional part" do
|
@@ -253,7 +257,7 @@ describe JsRoutes, "compatibility with Rails" do
|
|
253
257
|
|
254
258
|
context "and including them" do
|
255
259
|
it "should fail when insufficient arguments are given" do
|
256
|
-
expect { evaljs("Routes.thing_deep_path(2)") }.to raise_error(/Route
|
260
|
+
expect { evaljs("Routes.thing_deep_path(2)") }.to raise_error(/Route missing required keys: third_required/)
|
257
261
|
end
|
258
262
|
|
259
263
|
it "should include the optional parts" do
|
@@ -302,27 +306,22 @@ describe JsRoutes, "compatibility with Rails" do
|
|
302
306
|
evaljs("Routes.inbox_path()")
|
303
307
|
}.to raise_error(js_error_class)
|
304
308
|
end
|
309
|
+
|
305
310
|
it "should throw Exception if required parameter is not defined" do
|
306
311
|
expect {
|
307
312
|
evaljs("Routes.inbox_path(null)")
|
308
313
|
}.to raise_error(js_error_class)
|
309
314
|
end
|
310
315
|
|
311
|
-
it "should throw
|
312
|
-
expect {
|
313
|
-
evaljs("Routes.inbox_path(1,2,3)")
|
314
|
-
}.to raise_error(js_error_class)
|
315
|
-
end
|
316
|
-
|
317
|
-
it "should throw Exceptions if when pass id with null" do
|
316
|
+
it "should throw Exception if required parameter is not defined" do
|
318
317
|
expect {
|
319
|
-
evaljs("Routes.inbox_path(
|
318
|
+
evaljs("Routes.inbox_path(undefined)")
|
320
319
|
}.to raise_error(js_error_class)
|
321
320
|
end
|
322
321
|
|
323
|
-
it "should throw Exceptions if when
|
322
|
+
it "should throw Exceptions if when there is too many parameters" do
|
324
323
|
expect {
|
325
|
-
evaljs("Routes.inbox_path(
|
324
|
+
evaljs("Routes.inbox_path(1,2,3)")
|
326
325
|
}.to raise_error(js_error_class)
|
327
326
|
end
|
328
327
|
end
|
@@ -341,8 +340,19 @@ describe JsRoutes, "compatibility with Rails" do
|
|
341
340
|
let(:klass) { Struct.new(:id, :to_param) }
|
342
341
|
let(:inbox) { klass.new(1,"my") }
|
343
342
|
|
343
|
+
it "should throw Exceptions if when pass id with null" do
|
344
|
+
expect {
|
345
|
+
evaljs("Routes.inbox_path({id: null})")
|
346
|
+
}.to raise_error(js_error_class)
|
347
|
+
end
|
348
|
+
|
349
|
+
it "should throw Exceptions if when pass to_param with null" do
|
350
|
+
expect {
|
351
|
+
evaljs("Routes.inbox_path({to_param: null})")
|
352
|
+
}.to raise_error(js_error_class)
|
353
|
+
end
|
344
354
|
it "should support 0 as a to_param option" do
|
345
|
-
expect(evaljs("Routes.inbox_path({to_param: 0})")).to eq(test_routes.inbox_path(0))
|
355
|
+
expect(evaljs("Routes.inbox_path({to_param: 0})")).to eq(test_routes.inbox_path(Struct.new(:to_param).new('0')))
|
346
356
|
end
|
347
357
|
|
348
358
|
it "should check for options special key" do
|
@@ -379,6 +389,14 @@ describe JsRoutes, "compatibility with Rails" do
|
|
379
389
|
)).to eq(test_routes.inbox_message_path(inbox, 2, :custom => true, :format => "json"))
|
380
390
|
end
|
381
391
|
|
392
|
+
it "supports camel case property name" do
|
393
|
+
expect(evaljs("Routes.inbox_path({id: 1, toParam: 'my'})")).to eq(test_routes.inbox_path(inbox))
|
394
|
+
end
|
395
|
+
|
396
|
+
it "supports camel case method name" do
|
397
|
+
expect(evaljs("Routes.inbox_path({id: 1, toParam: function(){ return 'my';}})")).to eq(test_routes.inbox_path(inbox))
|
398
|
+
end
|
399
|
+
|
382
400
|
context "when globbing" do
|
383
401
|
it "should prefer to_param property over id property" do
|
384
402
|
expect(evaljs("Routes.book_path({id: 1, to_param: 'my'}, 1)")).to eq(test_routes.book_path(inbox, 1))
|
@@ -398,6 +416,7 @@ describe JsRoutes, "compatibility with Rails" do
|
|
398
416
|
)).to eq(test_routes.book_path(inbox, 2, :custom => true, :format => "json"))
|
399
417
|
end
|
400
418
|
end
|
419
|
+
|
401
420
|
end
|
402
421
|
|
403
422
|
context "when specs" do
|
@@ -418,13 +437,13 @@ describe JsRoutes, "compatibility with Rails" do
|
|
418
437
|
end
|
419
438
|
end
|
420
439
|
|
421
|
-
describe "
|
440
|
+
describe "requiredParams" do
|
422
441
|
it "should show inbox spec" do
|
423
|
-
expect(evaljs("Routes.inbox_path.
|
442
|
+
expect(evaljs("Routes.inbox_path.requiredParams()").to_a).to eq(["id"])
|
424
443
|
end
|
425
444
|
|
426
445
|
it "should show inbox message spec" do
|
427
|
-
expect(evaljs("Routes.inbox_message_path.
|
446
|
+
expect(evaljs("Routes.inbox_message_path.requiredParams()").to_a).to eq(["inbox_id", "id"])
|
428
447
|
end
|
429
448
|
end
|
430
449
|
|
@@ -93,7 +93,7 @@ describe "after Rails initialization" do
|
|
93
93
|
Rails.application.config.assets.initialize_on_precompile = true
|
94
94
|
end
|
95
95
|
it "should render some javascript" do
|
96
|
-
expect(evaluate(ctx, 'js-routes.js')).to match(/
|
96
|
+
expect(evaluate(ctx, 'js-routes.js')).to match(/Utils\.define_module/)
|
97
97
|
end
|
98
98
|
end
|
99
99
|
context "and not initialize on precompile" do
|
@@ -101,7 +101,7 @@ describe "after Rails initialization" do
|
|
101
101
|
Rails.application.config.assets.initialize_on_precompile = false
|
102
102
|
end
|
103
103
|
it "should raise an exception if 3 version" do
|
104
|
-
expect(evaluate(ctx, 'js-routes.js')).to match(/
|
104
|
+
expect(evaluate(ctx, 'js-routes.js')).to match(/Utils\.define_module/)
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|