js-routes-1.3.3/0000755000004100000410000000000013124471555013510 5ustar www-datawww-datajs-routes-1.3.3/Rakefile0000644000004100000410000000151313124471555015155 0ustar www-datawww-data# encoding: utf-8 require 'rubygems' require 'bundler' begin Bundler.setup(:default, :development) rescue Bundler::BundlerError => e $stderr.puts e.message $stderr.puts "Run `bundle install` to install missing gems" exit e.status_code end require 'bundler/gem_tasks' require 'rspec/core' require 'rspec/core/rake_task' require 'appraisal' load "rails/tasks/routes.rake" RSpec::Core::RakeTask.new(:spec) task :test_all => :appraisal # test all rails task :default => :spec namespace :spec do task :routes do require './spec/spec_helper' require 'action_dispatch/routing/inspector' draw_routes all_routes = Rails.application.routes.routes inspector = ActionDispatch::Routing::RoutesInspector.new(all_routes) puts inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, ENV['CONTROLLER']) end end js-routes-1.3.3/Gemfile0000644000004100000410000000013513124471555015002 0ustar www-datawww-datasource "http://rubygems.org" # Specify your gem's dependencies in js-routes.gemspec gemspec js-routes-1.3.3/.rspec0000644000004100000410000000001013124471555014614 0ustar www-datawww-data--color js-routes-1.3.3/LICENSE.txt0000644000004100000410000000204113124471555015330 0ustar www-datawww-dataCopyright (c) 2011 Bogdan Gusiev Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. js-routes-1.3.3/spec/0000755000004100000410000000000013124471555014442 5ustar www-datawww-datajs-routes-1.3.3/spec/js_routes/0000755000004100000410000000000013124471555016457 5ustar www-datawww-datajs-routes-1.3.3/spec/js_routes/default_serializer_spec.rb0000644000004100000410000000047313124471555023677 0ustar www-datawww-datadescribe JsRoutes, "#default_serializer" do before(:each) do evaljs(JsRoutes.generate({})) end it "should provide this method" do expect(evaljs("Routes.default_serializer({a: 1, b: [2,3], c: {d: 4, e: 5}, f: ''})")).to eq( "a=1&b%5B%5D=2&b%5B%5D=3&c%5Bd%5D=4&c%5Be%5D=5&f=" ) end end js-routes-1.3.3/spec/js_routes/generated_javascript_spec.rb0000644000004100000410000000575213124471555024213 0ustar www-datawww-datarequire 'spec_helper' require "fileutils" describe JsRoutes do before(:each) do evaljs(JsRoutes.generate) end describe "generated js" do subject { JsRoutes.generate } it "should set the default serializer when none is configured" do is_expected.to match(%r(custom_serializer: null,\s+serialize: function\(object\) {\s+if \(\(this\.custom_serializer != null\) && this.get_object_type\(this\.custom_serializer\) === \"function\"\) {\s+return this\.custom_serializer\(object\);\s+} else {\s+return this\.default_serializer\(object\);\s+}\s+},)) end it "should include a comment in the header" do app_class = "App" is_expected.to include("File generated by js-routes #{JsRoutes::VERSION}") is_expected.to include("Based on Rails routes of #{app_class}") end it "should call route function for each route" do is_expected.to include("inboxes_path: Utils.route(") end it "should have correct function without arguments signature" do is_expected.to include("inboxes_path: Utils.route([[\"format\",false]]") end it "should have correct function with arguments signature" do is_expected.to include("inbox_message_path: Utils.route([[\"inbox_id\",true],[\"id\",true],[\"format\",false]]") end it "should have correct function signature with unordered hash" do is_expected.to include("inbox_message_attachment_path: Utils.route([[\"inbox_id\",true],[\"message_id\",true],[\"id\",true],[\"format\",false]]") end it "should have correct function comment with options argument" do is_expected.to include("// function(options)\n inboxes_path: Utils.route") end it "should have correct function comment with arguments" do is_expected.to include("// function(inbox_id, message_id, options)\n new_inbox_message_attachment_path: Utils.route") end it "routes should be sorted in alphabetical order" do expect(subject.index("book_path")).to be <= subject.index("inboxes_path") end end describe ".generate!" do let(:name) { Rails.root.join('app', 'assets', 'javascripts', 'routes.js') } before(:each) do FileUtils.rm_f(name) JsRoutes.generate!({:file => name}) end after(:each) do FileUtils.rm_f(name) end after(:all) do FileUtils.rm_f("#{File.dirname(__FILE__)}/../routes.js") # let(:name) is not available here end it "should not generate file before initialization" do # This method is alread fixed in Rails master # But in 3.2 stable we need to hack it like this if Rails.application.instance_variable_get("@initialized") pending end expect(File.exists?(name)).to be_falsey end end describe "compiled javascript asset" do subject { ERB.new(File.read("app/assets/javascripts/js-routes.js.erb")).result(binding) } it "should have js routes code" do is_expected.to include("inbox_message_path: Utils.route([[\"inbox_id\",true],[\"id\",true],[\"format\",false]]") end end end js-routes-1.3.3/spec/js_routes/rails_routes_compatibility_spec.rb0000644000004100000410000004376413124471555025500 0ustar www-datawww-datarequire "spec_helper" describe JsRoutes, "compatibility with Rails" do before(:each) do evaljs(JsRoutes.generate({})) end it "should generate collection routing" do expect(evaljs("Routes.inboxes_path()")).to eq(routes.inboxes_path()) end it "should generate member routing" do expect(evaljs("Routes.inbox_path(1)")).to eq(routes.inbox_path(1)) end it "should raise error if required argument is not passed" do expect { evaljs("Routes.thing_path()") } .to raise_error('Route parameter missing: id') expect { evaljs("Routes.search_path()") } .to raise_error('Route parameter missing: q') expect { evaljs("Routes.book_path()") } .to raise_error('Route parameter missing: title') expect { evaljs("Routes.book_title_path()") } .to raise_error('Route parameter missing: title') end it "should support 0 as a member parameter" do expect(evaljs("Routes.inbox_path(0)")).to eq(routes.inbox_path(0)) end it "should generate nested routing with one parameter" do expect(evaljs("Routes.inbox_messages_path(1)")).to eq(routes.inbox_messages_path(1)) end it "should generate nested routing" do expect(evaljs("Routes.inbox_message_path(1,2)")).to eq(routes.inbox_message_path(1, 2)) end it "should generate routing with format" do expect(evaljs("Routes.inbox_path(1, {format: 'json'})")).to eq(routes.inbox_path(1, :format => "json")) end it "should support routes with reserved javascript words as parameters" do expect(evaljs("Routes.object_path(1, 2)")).to eq(routes.object_path(1,2)) end it "should support routes with trailing_slash" do expect(evaljs("Routes.inbox_path(1, {trailing_slash: true})")).to eq(routes.inbox_path(1, trailing_slash: true)) end it "should support url anchor given as parameter" do expect(evaljs("Routes.inbox_path(1, {anchor: 'hello'})")).to eq(routes.inbox_path(1, :anchor => "hello")) end it "should support url anchor and get parameters" do expect(evaljs("Routes.inbox_path(1, {expanded: true, anchor: 'hello'})")).to eq(routes.inbox_path(1, :expanded => true, :anchor => "hello")) end it "should use irregular ActiveSupport pluralizations" do expect(evaljs("Routes.budgies_path()")).to eq(routes.budgies_path) expect(evaljs("Routes.budgie_path(1)")).to eq(routes.budgie_path(1)) expect(evaljs("Routes.budgy_path")).to eq(nil) expect(evaljs("Routes.budgie_descendents_path(1)")).to eq(routes.budgie_descendents_path(1)) end describe "when route has defaults" do it "should support route default format" do expect(evaljs("Routes.api_purchases_path()")).to eq(routes.api_purchases_path) end it 'should support route default subdomain' do expect(evaljs("Routes.backend_root_path()")).to eq(routes.backend_root_path) end it "should support default format override" do expect(evaljs("Routes.api_purchases_path({format: 'xml'})")).to eq(routes.api_purchases_path(format: 'xml')) end it "should support default format override by passing it in args" do expect(evaljs("Routes.api_purchases_path('xml')")).to eq(routes.api_purchases_path('xml')) end it "doesn't apply defaults to path" do expect(evaljs("Routes.with_defaults_path()")).to eq(routes.with_defaults_path) end end context "with rails engines" do it "should support simple route" do expect(evaljs("Routes.blog_app_posts_path()")).to eq(blog_routes.posts_path()) end it "should support root route" do expect(evaljs("Routes.blog_app_path()")).to eq(routes.blog_app_path()) end it "should support route with parameters" do expect(evaljs("Routes.blog_app_post_path(1)")).to eq(blog_routes.post_path(1)) end it "should support root path" do expect(evaljs("Routes.blog_app_root_path()")).to eq(blog_routes.root_path) end it "should support single route mapping" do expect(evaljs("Routes.support_path({page: 3})")).to eq(routes.support_path(:page => 3)) end end it "shouldn't require the format" do expect(evaljs("Routes.json_only_path({format: 'json'})")).to eq(routes.json_only_path(:format => 'json')) end it "should serialize object with empty string value" do expect(evaljs("Routes.inboxes_path({a: '', b: 1})")).to eq(routes.inboxes_path(:a => '', :b => 1)) end it "should support utf-8 route" do expect(evaljs("Routes.hello_path()")).to eq(routes.hello_path) end it "should support root_path" do expect(evaljs("Routes.root_path()")).to eq(routes.root_path) end describe "get paramters" do it "should support simple get parameters" do expect(evaljs("Routes.inbox_path(1, {format: 'json', lang: 'ua', q: 'hello'})")).to eq(routes.inbox_path(1, :lang => "ua", :q => "hello", :format => "json")) end it "should support array get parameters" do expect(evaljs("Routes.inbox_path(1, {hello: ['world', 'mars']})")).to eq(routes.inbox_path(1, :hello => [:world, :mars])) end it "should support nested get parameters" do expect(evaljs("Routes.inbox_path(1, {format: 'json', env: 'test', search: { category_ids: [2,5], q: 'hello'}})")).to eq( routes.inbox_path(1, :env => 'test', :search => {:category_ids => [2,5], :q => "hello"}, :format => "json") ) end it "should support null and undefined parameters" do expect(evaljs("Routes.inboxes_path({uri: null, key: undefined})")).to eq(routes.inboxes_path(:uri => nil, :key => nil)) end it "should escape get parameters" do expect(evaljs("Routes.inboxes_path({uri: 'http://example.com'})")).to eq(routes.inboxes_path(:uri => 'http://example.com')) end end context "routes globbing" do it "should be supported as parameters" do expect(evaljs("Routes.book_path('thrillers', 1)")).to eq(routes.book_path('thrillers', 1)) end it "should support routes globbing as array" do expect(evaljs("Routes.book_path(['thrillers'], 1)")).to eq(routes.book_path(['thrillers'], 1)) end it "should bee support routes globbing as array" do expect(evaljs("Routes.book_path([1, 2, 3], 1)")).to eq(routes.book_path([1, 2, 3], 1)) end it "should bee support routes globbing as hash" do expect(evaljs("Routes.book_path('a_test/b_test/c_test', 1)")).to eq(routes.book_path('a_test/b_test/c_test', 1)) end it "should support routes globbing as array with optional params" do expect(evaljs("Routes.book_path([1, 2, 3, 5], 1, {c: '1'})")).to eq(routes.book_path([1, 2, 3, 5], 1, { :c => "1" })) end it "should support routes globbing in book_title route as array" do expect(evaljs("Routes.book_title_path('john', ['thrillers', 'comedian'])")).to eq(routes.book_title_path('john', ['thrillers', 'comedian'])) end it "should support routes globbing in book_title route as array with optional params" do expect(evaljs("Routes.book_title_path('john', ['thrillers', 'comedian'], {some_key: 'some_value'})")).to eq(routes.book_title_path('john', ['thrillers', 'comedian'], {:some_key => 'some_value'})) end it "should support required paramters given as options hash" do expect(evaljs("Routes.search_path({q: 'hello'})")).to eq(routes.search_path(:q => 'hello')) end it "should support nested object null parameters" do expect(evaljs("Routes.inboxes_path({hello: {world: null}})")).to eq(routes.inboxes_path(:hello => {:world => nil})) end end context "using optional path fragments" do context "including not optional parts" do it "should include everything that is not optional" do expect(evaljs("Routes.foo_path()")).to eq(routes.foo_path) end end context "but not including them" do it "should not include the optional parts" do expect(evaljs("Routes.things_path()")).to eq(routes.things_path) expect(evaljs("Routes.things_path({ q: 'hello' })")).to eq(routes.things_path(q: 'hello')) end it "should not require the optional parts as arguments" do expect(evaljs("Routes.thing_path(null, 5)")).to eq(routes.thing_path(nil, 5)) end it "should treat undefined as non-given optional part" do expect(evaljs("Routes.thing_path(5, {optional_id: undefined})")).to eq(routes.thing_path(5, :optional_id => nil)) end it "should raise error when passing non-full list of arguments and some query params" do expect { evaljs("Routes.thing_path(5, {q: 'hello'})") } .to raise_error('Route parameter missing: id') end it "should treat null as non-given optional part" do expect(evaljs("Routes.thing_path(5, {optional_id: null})")).to eq(routes.thing_path(5, :optional_id => nil)) end it "should work when passing required params in options" do expect(evaljs("Routes.thing_deep_path({second_required: 1, third_required: 2})")).to eq(routes.thing_deep_path(second_required: 1, third_required: 2)) end it "should skip leading and trailing optional parts" do skip if Rails.version < '4' expect(evaljs("Routes.thing_deep_path(1, 2)")).to eq(routes.thing_deep_path(1, 2)) end end context "and including them" do if Rails.version < '4' it "should fail when insufficient arguments are given" do expect { evaljs("Routes.thing_deep_path(1)")} .to raise_error('Route parameter missing: second_required') expect { evaljs("Routes.thing_deep_path(1,2)")} .to raise_error('Route parameter missing: third_required') end end it "should include the optional parts" do expect(evaljs("Routes.things_path({optional_id: 5})")).to eq(routes.things_path(:optional_id => 5)) expect(evaljs("Routes.things_path(5)")).to eq(routes.things_path(5)) expect(evaljs("Routes.thing_deep_path(1, { third_required: 3, second_required: 2 })")).to eq(routes.thing_deep_path(1, third_required: 3, second_required: 2)) expect(evaljs("Routes.thing_deep_path(1, { third_required: 3, second_required: 2, forth_optional: 4 })")).to eq(routes.thing_deep_path(1, third_required: 3, second_required: 2, forth_optional: 4)) expect(evaljs("Routes.thing_deep_path(2, { third_required: 3, first_optional: 1 })")).to eq(routes.thing_deep_path(2, third_required: 3, first_optional: 1)) expect(evaljs("Routes.thing_deep_path(3, { first_optional: 1, second_required: 2 })")).to eq(routes.thing_deep_path(3, first_optional: 1, second_required: 2)) expect(evaljs("Routes.thing_deep_path(3, { first_optional: 1, second_required: 2, forth_optional: 4 })")).to eq(routes.thing_deep_path(3, first_optional: 1, second_required: 2, forth_optional: 4)) expect(evaljs("Routes.thing_deep_path(4, { first_optional: 1, second_required: 2, third_required: 3 })")).to eq(routes.thing_deep_path(4, first_optional: 1, second_required: 2, third_required: 3)) expect(evaljs("Routes.thing_deep_path(1, 2, { third_required: 3 })")).to eq(routes.thing_deep_path(1, 2, third_required: 3)) expect(evaljs("Routes.thing_deep_path(1,2, {third_required: 3, q: 'bogdan'})")).to eq(routes.thing_deep_path(1,2, {third_required: 3, q: 'bogdan'})) expect(evaljs("Routes.thing_deep_path(1, 2, { forth_optional: 4, third_required: 3 })")).to eq(routes.thing_deep_path(1, 2, forth_optional: 4, third_required: 3)) expect(evaljs("Routes.thing_deep_path(1, 3, { second_required: 2 })")).to eq(routes.thing_deep_path(1, 3, second_required: 2)) expect(evaljs("Routes.thing_deep_path(1, 4, { second_required: 2, third_required: 3 })")).to eq(routes.thing_deep_path(1, 4, second_required: 2, third_required: 3)) expect(evaljs("Routes.thing_deep_path(2, 3, { first_optional: 1 })")).to eq(routes.thing_deep_path(2, 3, first_optional: 1)) expect(evaljs("Routes.thing_deep_path(2, 3, { first_optional: 1, forth_optional: 4 })")).to eq(routes.thing_deep_path(2, 3, first_optional: 1, forth_optional: 4)) expect(evaljs("Routes.thing_deep_path(2, 4, { first_optional: 1, third_required: 3 })")).to eq(routes.thing_deep_path(2, 4, first_optional: 1, third_required: 3)) expect(evaljs("Routes.thing_deep_path(3, 4, { first_optional: 1, second_required: 2 })")).to eq(routes.thing_deep_path(3, 4, first_optional: 1, second_required: 2)) expect(evaljs("Routes.thing_deep_path(1, 2, 3)")).to eq(routes.thing_deep_path(1, 2, 3)) expect(evaljs("Routes.thing_deep_path(1, 2, 3, { forth_optional: 4 })")).to eq(routes.thing_deep_path(1, 2, 3, forth_optional: 4)) expect(evaljs("Routes.thing_deep_path(1, 2, 4, { third_required: 3 })")).to eq(routes.thing_deep_path(1, 2, 4, third_required: 3)) expect(evaljs("Routes.thing_deep_path(1, 3, 4, { second_required: 2 })")).to eq(routes.thing_deep_path(1, 3, 4, second_required: 2)) expect(evaljs("Routes.thing_deep_path(2, 3, 4, { first_optional: 1 })")).to eq(routes.thing_deep_path(2, 3, 4, first_optional: 1)) expect(evaljs("Routes.thing_deep_path(1, 2, 3, 4)")).to eq(routes.thing_deep_path(1, 2, 3, 4)) end context "on nested optional parts" do if Rails.version <= "5.0.0" # this type of routing is deprecated it "should include everything that is not optional" do expect(evaljs("Routes.classic_path({controller: 'classic', action: 'edit'})")).to eq(routes.classic_path(controller: :classic, action: :edit)) end end end end end context "when wrong parameters given" do it "should throw Exception if not enough parameters" do expect { evaljs("Routes.inbox_path()") }.to raise_error(js_error_class) end it "should throw Exception if required parameter is not defined" do expect { evaljs("Routes.inbox_path(null)") }.to raise_error(js_error_class) end it "should throw Exceptions if when there is too many parameters" do expect { evaljs("Routes.inbox_path(1,2,3)") }.to raise_error(js_error_class) end it "should throw Exceptions if when pass id with null" do expect { evaljs("Routes.inbox_path({id: null})") }.to raise_error(js_error_class) end it "should throw Exceptions if when pass to_param with null" do expect { evaljs("Routes.inbox_path({to_param: null})") }.to raise_error(js_error_class) end end context "when javascript engine without Array#indexOf is used" do before(:each) do evaljs("Array.prototype.indexOf = null") end it "should still work correctly" do expect(evaljs("Routes.inboxes_path()")).to eq(routes.inboxes_path()) end end context "when arguments are objects" do let(:klass) { Struct.new(:id, :to_param) } let(:inbox) { klass.new(1,"my") } it "should support 0 as a to_param option" do expect(evaljs("Routes.inbox_path({to_param: 0})")).to eq(routes.inbox_path(0)) end it "should check for options special key" do expect(evaljs("Routes.inbox_path({id: 7, q: 'hello', _options: true})")).to eq(routes.inbox_path(id: 7, q: 'hello')) expect { evaljs("Routes.inbox_path({to_param: 7, _options: true})") }.to raise_error(js_error_class) expect(evaljs("Routes.inbox_message_path(5, {id: 7, q: 'hello', _options: true})")).to eq(routes.inbox_message_path(5, id: 7, q: 'hello')) end it "should check for options special key" do end it "should support 0 as an id option" do expect(evaljs("Routes.inbox_path({id: 0})")).to eq(routes.inbox_path(0)) end it "should use id property of the object in path" do expect(evaljs("Routes.inbox_path({id: 1})")).to eq(routes.inbox_path(1)) end it "should prefer to_param property over id property" do expect(evaljs("Routes.inbox_path({id: 1, to_param: 'my'})")).to eq(routes.inbox_path(inbox)) end it "should call to_param if it is a function" do expect(evaljs("Routes.inbox_path({id: 1, to_param: function(){ return 'my';}})")).to eq(routes.inbox_path(inbox)) end it "should call id if it is a function" do expect(evaljs("Routes.inbox_path({id: function() { return 1;}})")).to eq(routes.inbox_path(1)) end it "should support options argument" do expect(evaljs( "Routes.inbox_message_path({id:1, to_param: 'my'}, {id:2}, {custom: true, format: 'json'})" )).to eq(routes.inbox_message_path(inbox, 2, :custom => true, :format => "json")) end context "when globbing" do it "should prefer to_param property over id property" do expect(evaljs("Routes.book_path({id: 1, to_param: 'my'}, 1)")).to eq(routes.book_path(inbox, 1)) end it "should call to_param if it is a function" do expect(evaljs("Routes.book_path({id: 1, to_param: function(){ return 'my';}}, 1)")).to eq(routes.book_path(inbox, 1)) end it "should call id if it is a function" do expect(evaljs("Routes.book_path({id: function() { return 'technical';}}, 1)")).to eq(routes.book_path('technical', 1)) end it "should support options argument" do expect(evaljs( "Routes.book_path({id:1, to_param: 'my'}, {id:2}, {custom: true, format: 'json'})" )).to eq(routes.book_path(inbox, 2, :custom => true, :format => "json")) end end end context "when specs" do it "should show inbox spec" do expect(evaljs("Routes.inbox_path.toString()")).to eq('/inboxes/:id(.:format)') end it "should show inbox spec convert to string" do expect(evaljs("'' + Routes.inbox_path")).to eq('/inboxes/:id(.:format)') end it "should show inbox message spec" do expect(evaljs("Routes.inbox_message_path.toString()")).to eq('/inboxes/:inbox_id/messages/:id(.:format)') end it "should show inbox message spec convert to string" do expect(evaljs("'' + Routes.inbox_message_path")).to eq('/inboxes/:inbox_id/messages/:id(.:format)') end end describe "required_params" do it "should show inbox spec" do expect(evaljs("Routes.inbox_path.required_params").to_a).to eq(["id"]) end it "should show inbox message spec" do expect(evaljs("Routes.inbox_message_path.required_params").to_a).to eq(["inbox_id", "id"]) end end end js-routes-1.3.3/spec/js_routes/amd_compatibility_spec.rb0000644000004100000410000000235613124471555023516 0ustar www-datawww-datarequire "spec_helper" describe JsRoutes, "compatibility with AMD/require.js" do before(:each) do evaljs("window.GlobalCheck = {};") evaljs("window.define = function (requirs, callback) { window.GlobalCheck['js-routes'] = callback.call(this); return window.GlobalCheck['js-routes']; };") evaljs("window.define.amd = { jQuery: true };") strRequire =< "myCustomSerializer"} } it "should set configurable serializer" do # expect the nonsense serializer above to have appened foo=bar # to the end of the path expect(evaljs(%q(Routes.inboxes_path()))).to eql("/inboxes?foo=bar") end end context "when serializer is specified, but not function" do let(:_presetup){ %q(var myCustomSerializer = 1) } let(:_options) { {:serializer => "myCustomSerializer"} } it "should set configurable serializer" do # expect to use default expect(evaljs(%q(Routes.inboxes_path({a: 1})))).to eql("/inboxes?a=1") end end context "when exclude is specified" do let(:_options) { {:exclude => /^admin_/} } it "should exclude specified routes from file" do expect(evaljs("Routes.admin_users_path")).to be_nil end it "should not exclude routes not under specified pattern" do expect(evaljs("Routes.inboxes_path()")).not_to be_nil end context "for rails engine" do let(:_options) { {:exclude => /^blog_app_posts/} } it "should exclude specified engine route" do expect(evaljs("Routes.blog_app_posts_path")).to be_nil end end end context "when include is specified" do let(:_options) { {:include => /^admin_/} } it "should exclude specified routes from file" do expect(evaljs("Routes.admin_users_path()")).not_to be_nil end it "should not exclude routes not under specified pattern" do expect(evaljs("Routes.inboxes_path")).to be_nil end context "for rails engine" do let(:_options) { {:include => /^blog_app_posts/} } it "should include specified engine route" do expect(evaljs("Routes.blog_app_posts_path()")).not_to be_nil end end end context "when prefix with trailing slash is specified" do let(:_options) { {:prefix => "/myprefix/" } } it "should render routing with prefix" do expect(evaljs("Routes.inbox_path(1)")).to eq("/myprefix#{routes.inbox_path(1)}") end it "should render routing with prefix set in JavaScript" do evaljs("Routes.options.prefix = '/newprefix/'") expect(evaljs("Routes.inbox_path(1)")).to eq("/newprefix#{routes.inbox_path(1)}") end end context "when prefix with http:// is specified" do let(:_options) { {:prefix => "http://localhost:3000" } } it "should render routing with prefix" do expect(evaljs("Routes.inbox_path(1)")).to eq(_options[:prefix] + routes.inbox_path(1)) end end context "when prefix without trailing slash is specified" do let(:_options) { {:prefix => "/myprefix" } } it "should render routing with prefix" do expect(evaljs("Routes.inbox_path(1)")).to eq("/myprefix#{routes.inbox_path(1)}") end it "should render routing with prefix set in JavaScript" do evaljs("Routes.options.prefix = '/newprefix'") expect(evaljs("Routes.inbox_path(1)")).to eq("/newprefix#{routes.inbox_path(1)}") end end context "when default_format is specified" do let(:_options) { {:default_format => "json"} } let(:_warnings) { nil } it "should render routing with default_format" do expect(evaljs("Routes.inbox_path(1)")).to eq(routes.inbox_path(1, :format => "json")) end it "should render routing with default_format and zero object" do expect(evaljs("Routes.inbox_path(0)")).to eq(routes.inbox_path(0, :format => "json")) end it "should override default_format when spefified implicitly" do expect(evaljs("Routes.inbox_path(1, {format: 'xml'})")).to eq(routes.inbox_path(1, :format => "xml")) end it "should override nullify implicitly when specified implicitly" do expect(evaljs("Routes.inbox_path(1, {format: null})")).to eq(routes.inbox_path(1)) end it "shouldn't require the format" do pending if Rails.version < "4.0" expect(evaljs("Routes.json_only_path()")).to eq(routes.json_only_path(:format => 'json')) end end it "shouldn't include the format when {:format => false} is specified" do expect(evaljs("Routes.no_format_path()")).to eq(routes.no_format_path()) expect(evaljs("Routes.no_format_path({format: 'json'})")).to eq(routes.no_format_path(format: 'json')) end describe "when namespace option is specified" do let(:_options) { {:namespace => "PHM"} } it "should use this namespace for routing" do expect(evaljs("window.Routes")).to be_nil expect(evaljs("PHM.inbox_path")).not_to be_nil end end describe "when nested namespace option is specified" do context "and defined on client" do let(:_presetup) { "window.PHM = {}" } let(:_options) { {:namespace => "PHM.Routes"} } it "should use this namespace for routing" do expect(evaljs("PHM.Routes.inbox_path")).not_to be_nil end end context "but undefined on client" do let(:_options) { {:namespace => "PHM.Routes"} } it "should initialize namespace" do expect(evaljs("window.PHM.Routes.inbox_path")).not_to be_nil end end context "and some parts are defined" do let(:_presetup) { "window.PHM = { Utils: {} };" } let(:_options) { {:namespace => "PHM.Routes"} } it "should not overwrite existing parts" do expect(evaljs("window.PHM.Utils")).not_to be_nil expect(evaljs("window.PHM.Routes.inbox_path")).not_to be_nil end end end describe "default_url_options" do context "with optional route parts" do context "provided" do let(:_options) { { :default_url_options => { :optional_id => "12", :format => "json" } } } it "should use this opions to fill optional parameters" do expect(evaljs("Routes.things_path()")).to eq(routes.things_path(:optional_id => 12, :format => "json")) end end context "not provided" do let(:_options) { { :default_url_options => { :format => "json" } } } it "breaks" do expect(evaljs("Routes.foo_all_path()")).to eq(routes.foo_all_path(:format => "json")) end end end context "with required route parts" do let(:_options) { {:default_url_options => {:inbox_id => "12"}} } it "should use this opions to fill optional parameters" do expect(evaljs("Routes.inbox_messages_path()")).to eq(routes.inbox_messages_path(:inbox_id => 12)) end end end describe "trailing_slash" do context "with default option" do let(:_options) { Hash.new } it "should working in params" do expect(evaljs("Routes.inbox_path(1, {trailing_slash: true})")).to eq(routes.inbox_path(1, :trailing_slash => true)) end it "should working with additional params" do expect(evaljs("Routes.inbox_path(1, {trailing_slash: true, test: 'params'})")).to eq(routes.inbox_path(1, :trailing_slash => true, :test => 'params')) end end context "with default_url_options option" do let(:_options) { {:default_url_options => {:trailing_slash => true}} } it "should working" do expect(evaljs("Routes.inbox_path(1, {test: 'params'})")).to eq(routes.inbox_path(1, :trailing_slash => true, :test => 'params')) end it "should remove it by params" do expect(evaljs("Routes.inbox_path(1, {trailing_slash: false})")).to eq(routes.inbox_path(1)) end end context "with disabled default_url_options option" do let(:_options) { {:default_url_options => {:trailing_slash => false}} } it "should not use trailing_slash" do expect(evaljs("Routes.inbox_path(1, {test: 'params'})")).to eq(routes.inbox_path(1, :test => 'params')) end it "should use it by params" do expect(evaljs("Routes.inbox_path(1, {trailing_slash: true})")).to eq(routes.inbox_path(1, :trailing_slash => true)) end end end describe "camel_case" do context "with default option" do let(:_options) { Hash.new } it "should use snake case routes" do expect(evaljs("Routes.inbox_path(1)")).to eq(routes.inbox_path(1)) expect(evaljs("Routes.inboxPath")).to be_nil end end context "with true" do let(:_options) { { :camel_case => true } } it "should generate camel case routes" do expect(evaljs("Routes.inbox_path")).to be_nil expect(evaljs("Routes.inboxPath")).not_to be_nil expect(evaljs("Routes.inboxPath(1)")).to eq(routes.inbox_path(1)) expect(evaljs("Routes.inboxMessagesPath(10)")).to eq(routes.inbox_messages_path(:inbox_id => 10)) end end end describe "url_links" do context "with default option" do let(:_options) { Hash.new } it "should generate only path links" do expect(evaljs("Routes.inbox_path(1)")).to eq(routes.inbox_path(1)) expect(evaljs("Routes.inbox_url")).to be_nil end end context 'with deprecated, non-boolean config value' do around(:each) do |example| ActiveSupport::Deprecation.silence do example.run end end context "with host" do let(:_options) { { :url_links => "http://localhost" } } it "should generate path and url links" do expect(evaljs("Routes.inbox_path")).not_to be_nil expect(evaljs("Routes.inbox_url")).not_to be_nil expect(evaljs("Routes.inbox_path(1)")).to eq(routes.inbox_path(1)) expect(evaljs("Routes.inbox_url(1)")).to eq("http://localhost#{routes.inbox_path(1)}") expect(evaljs("Routes.inbox_url(1, { test_key: \"test_val\" })")).to eq("http://localhost#{routes.inbox_path(1, :test_key => "test_val")}") end end context "with invalid host" do it "should raise error" do expect { JsRoutes.generate({ :url_links => "localhost" }) }.to raise_error RuntimeError end end context "with host and camel_case" do let(:_options) { { :camel_case => true, :url_links => "http://localhost" } } it "should generate path and url links" do expect(evaljs("Routes.inboxPath")).not_to be_nil expect(evaljs("Routes.inboxUrl")).not_to be_nil expect(evaljs("Routes.inboxPath(1)")).to eq(routes.inbox_path(1)) expect(evaljs("Routes.inboxUrl(1)")).to eq("http://localhost#{routes.inbox_path(1)}") end end context "with host and prefix" do let(:_options) { { :prefix => "/api", :url_links => "https://example.com" } } it "should generate path and url links" do expect(evaljs("Routes.inbox_path")).not_to be_nil expect(evaljs("Routes.inbox_url")).not_to be_nil expect(evaljs("Routes.inbox_path(1)")).to eq("/api#{routes.inbox_path(1)}") expect(evaljs("Routes.inbox_url(1)")).to eq("https://example.com/api#{routes.inbox_path(1)}") end end end context "when configuring with default_url_options" do context "when only host option is specified" do let(:_options) { { :url_links => true, :default_url_options => {:host => "example.com"} } } it "uses the specified host, defaults protocol to http, defaults port to 80 (leaving it blank)" do expect(evaljs("Routes.inbox_url(1)")).to eq("http://example.com#{routes.inbox_path(1)}") end it "does not override protocol when specified in route" do expect(evaljs("Routes.new_session_url()")).to eq("https://example.com#{routes.new_session_path}") end it "does not override host when specified in route" do expect(evaljs("Routes.sso_url()")).to eq(routes.sso_url) end it "does not override port when specified in route" do expect(evaljs("Routes.portals_url()")).to eq("http://example.com:8080#{routes.portals_path}") end end context "when default host and protocol are specified" do let(:_options) { { :url_links => true, :default_url_options => {:host => "example.com", :protocol => "ftp"} } } it "uses the specified protocol and host, defaults port to 80 (leaving it blank)" do expect(evaljs("Routes.inbox_url(1)")).to eq("ftp://example.com#{routes.inbox_path(1)}") end it "does not override protocol when specified in route" do expect(evaljs("Routes.new_session_url()")).to eq("https://example.com#{routes.new_session_path}") end it "does not override host when host is specified in route" do expect(evaljs("Routes.sso_url()")).to eq("ftp://sso.example.com#{routes.sso_path}") end it "does not override port when specified in route" do expect(evaljs("Routes.portals_url()")).to eq("ftp://example.com:8080#{routes.portals_path}") end end context "when default host and port are specified" do let(:_options) { { :url_links => true, :default_url_options => {:host => "example.com", :port => 3000} } } it "uses the specified host and port, defaults protocol to http" do expect(evaljs("Routes.inbox_url(1)")).to eq("http://example.com:3000#{routes.inbox_path(1)}") end it "does not override protocol when specified in route" do expect(evaljs("Routes.new_session_url()")).to eq("https://example.com:3000#{routes.new_session_path}") end it "does not override host, protocol, or port when host is specified in route" do expect(evaljs("Routes.sso_url()")).to eq("http://sso.example.com:3000" + routes.sso_path) end it "does not override port when specified in route" do expect(evaljs("Routes.portals_url()")).to eq("http://example.com:8080#{routes.portals_path}") end end context "with camel_case option" do let(:_options) { { :camel_case => true, :url_links => true, :default_url_options => {:host => "example.com"} } } it "should generate path and url links" do expect(evaljs("Routes.inboxUrl(1)")).to eq("http://example.com#{routes.inbox_path(1)}") expect(evaljs("Routes.newSessionUrl()")).to eq("https://example.com#{routes.new_session_path}") expect(evaljs("Routes.ssoUrl()")).to eq(routes.sso_url) expect(evaljs("Routes.portalsUrl()")).to eq("http://example.com:8080#{routes.portals_path}") end end context "with prefix option" do let(:_options) { { :prefix => "/api", :url_links => true, :default_url_options => {:host => 'example.com'} } } it "should generate path and url links" do expect(evaljs("Routes.inbox_url(1)")).to eq("http://example.com/api#{routes.inbox_path(1)}") expect(evaljs("Routes.new_session_url()")).to eq("https://example.com/api#{routes.new_session_path}") expect(evaljs("Routes.sso_url()")).to eq("http://sso.example.com/api#{routes.sso_path}") expect(evaljs("Routes.portals_url()")).to eq("http://example.com:8080/api#{routes.portals_path}") end end context "with compact option" do let(:_options) { { :compact => true, :url_links => true, :default_url_options => {:host => 'example.com'} } } it "does not affect url helpers" do expect(evaljs("Routes.inbox_url(1)")).to eq("http://example.com#{routes.inbox_path(1)}") expect(evaljs("Routes.new_session_url()")).to eq("https://example.com#{routes.new_session_path}") expect(evaljs("Routes.sso_url()")).to eq(routes.sso_url) expect(evaljs("Routes.portals_url()")).to eq("http://example.com:8080#{routes.portals_path}") end end end context 'when window.location is present' do let(:current_protocol) { 'http:' } # window.location.protocol includes the colon character let(:current_hostname) { 'current.example.com' } let(:current_port){ '' } # an empty string means port 80 let(:current_host) do host = "#{current_hostname}" host += ":#{current_port}" unless current_port == '' host end before do jscontext.eval("window = {'location': {'protocol': '#{current_protocol}', 'hostname': '#{current_hostname}', 'port': '#{current_port}', 'host': '#{current_host}'}}") end context "without specifying a default host" do let(:_options) { { :url_links => true } } it "uses the current host" do expect(evaljs("Routes.inbox_path")).not_to be_nil expect(evaljs("Routes.inbox_url")).not_to be_nil expect(evaljs("Routes.inbox_url(1)")).to eq("http://current.example.com#{routes.inbox_path(1)}") expect(evaljs("Routes.inbox_url(1, { test_key: \"test_val\" })")).to eq("http://current.example.com#{routes.inbox_path(1, :test_key => "test_val")}") expect(evaljs("Routes.new_session_url()")).to eq("https://current.example.com#{routes.new_session_path}") expect(evaljs("Routes.sso_url()")).to eq("http://sso.example.com#{routes.sso_path}") end it "uses host option as an argument" do expect(evaljs("Routes.portals_url({host: 'another.com'})")).to eq(routes.portals_url(host: 'another.com')) end it "uses port option as an argument" do expect(evaljs("Routes.portals_url({host: 'localhost', port: 8080})")).to eq(routes.portals_url(host: 'localhost', port: 8080)) end it "uses protocol option as an argument" do expect(evaljs("Routes.portals_url({host: 'localhost', protocol: 'https'})")).to eq(routes.portals_url(protocol: 'https', host: 'localhost')) end end end end describe "when the compact mode is enabled" do let(:_options) { { :compact => true } } it "removes _path suffix from path helpers" do expect(evaljs("Routes.inbox_path")).to be_nil expect(evaljs("Routes.inboxes()")).to eq(routes.inboxes_path()) expect(evaljs("Routes.inbox(2)")).to eq(routes.inbox_path(2)) end context "with url_links option" do context "with deprecated url_links config value" do around(:each) do |example| ActiveSupport::Deprecation.silence do example.run end end let(:_options) { { :compact => true, :url_links => "http://localhost" } } it "should not strip urls" do expect(evaljs("Routes.inbox(1)")).to eq(routes.inbox_path(1)) expect(evaljs("Routes.inbox_url(1)")).to eq("http://localhost#{routes.inbox_path(1)}") end end end end describe "special_options_key" do let(:_options) { { special_options_key: :__options__ } } it "can be redefined" do expect { expect(evaljs("Routes.inbox_message_path({inbox_id: 1, id: 2, _options: true})")).to eq("") }.to raise_error(js_error_class) expect(evaljs("Routes.inbox_message_path({inbox_id: 1, id: 2, __options__: true})")).to eq(routes.inbox_message_path(inbox_id: 1, id: 2)) end end describe "when application is specified" do let(:_options) { {:application => BlogEngine::Engine} } it "should include specified engine route" do expect(evaljs("Routes.posts_path()")).not_to be_nil end end end js-routes-1.3.3/spec/js_routes/zzz_last_post_rails_init_spec.rb0000644000004100000410000000707013124471555025164 0ustar www-datawww-data# we need to run post_rails_init_spec as the latest # because it cause unrevertable changes to runtime # what is why I added "zzz_last" in the beginning require 'spec_helper' require "fileutils" describe "after Rails initialization" do NAME = Rails.root.join('app', 'assets', 'javascripts', 'routes.js').to_s def sprockets_v3? Sprockets::VERSION.to_i >= 3 end def sprockets_context(environment, name, filename) if sprockets_v3? Sprockets::Context.new(environment: environment, name: name, filename: filename.to_s, metadata: {}) else Sprockets::Context.new(environment, name, filename) end end def evaluate(ctx, file) if sprockets_v3? ctx.load(ctx.environment.find_asset(file, pipeline: :default).uri).to_s else ctx.evaluate(file) end end before(:each) do FileUtils.rm_rf Rails.root.join('tmp/cache') FileUtils.rm_f NAME JsRoutes.generate!(NAME) end before(:all) do Rails.configuration.eager_load = false Rails.application.initialize! end it "should generate routes file" do expect(File.exists?(NAME)).to be_truthy end context "JsRoutes::Engine" do TEST_ASSET_PATH = Rails.root.join('app','assets','javascripts','test.js') before(:all) do File.open(TEST_ASSET_PATH,'w') do |f| f.puts "function() {}" end end after(:all) do FileUtils.rm_f(TEST_ASSET_PATH) end context "the preprocessor" do before(:each) do path = Rails.root.join('config','routes.rb').to_s if sprockets_v3? expect_any_instance_of(Sprockets::Context).to receive(:depend_on).with(path) else expect(ctx).to receive(:depend_on).with(path) end end let!(:ctx) do sprockets_context(Rails.application.assets, 'js-routes.js', Pathname.new('js-routes.js')) end context "when dealing with js-routes.js" do context "with Rails" do context "and initialize on precompile" do before(:each) do Rails.application.config.assets.initialize_on_precompile = true end it "should render some javascript" do expect(evaluate(ctx, 'js-routes.js')).to match(/root\.Routes/) end end context "and not initialize on precompile" do before(:each) do Rails.application.config.assets.initialize_on_precompile = false end it "should raise an exception if 3 version" do if 3 == Rails::VERSION::MAJOR expect { evaluate(ctx, 'js-routes.js') }.to raise_error(/Cannot precompile/) else expect(evaluate(ctx, 'js-routes.js')).to match(/root\.Routes/) end end end end end end context "when not dealing with js-routes.js" do it "should not depend on routes.rb" do ctx = sprockets_context(Rails.application.assets, 'test.js', TEST_ASSET_PATH) expect(ctx).not_to receive(:depend_on) evaluate(ctx, 'test.js') end end end end describe "JSRoutes thread safety" do before do begin Rails.application.initialize! rescue end end it "can produce the routes from multiple threads" do threads = 2.times.map do Thread.start do 10.times { expect { JsRoutes.generate }.to_not raise_error } end end threads.each do |thread| thread.join end end end js-routes-1.3.3/spec/spec_helper.rb0000644000004100000410000000515413124471555017265 0ustar www-datawww-data# encoding: utf-8 $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) $:.unshift(File.dirname(__FILE__)) require 'rspec' require 'rails/all' require 'js-routes' require 'active_support/core_ext/hash/slice' require 'coffee-script' # fix ends_with? error for rails 3.2 require 'active_support/core_ext/string/starts_ends_with' if 3 == Rails::VERSION::MAJOR if defined?(JRUBY_VERSION) require 'rhino' JS_LIB_CLASS = Rhino else require 'v8' JS_LIB_CLASS = V8 end def jscontext(force = false) if force @jscontext = JS_LIB_CLASS::Context.new else @jscontext ||= JS_LIB_CLASS::Context.new end end def js_error_class JS_LIB_CLASS::JSError end def evaljs(string, force = false) jscontext(force).eval(string) end def routes App.routes.url_helpers end def blog_routes BlogEngine::Engine.routes.url_helpers end ActiveSupport::Inflector.inflections do |inflect| inflect.irregular "budgie", "budgies" end module BlogEngine class Engine < Rails::Engine isolate_namespace BlogEngine end end class App < Rails::Application # Enable the asset pipeline config.assets.enabled = true # initialize_on_precompile config.assets.initialize_on_precompile = true if 3 == Rails::VERSION::MAJOR config.paths['config/routes'] << 'spec/config/routes.rb' else config.paths['config/routes.rb'] << 'spec/config/routes.rb' end config.root = File.expand_path('../dummy', __FILE__) end # prevent warning Rails.configuration.active_support.deprecation = :log # Requires supporting files with custom matchers and macros, etc, # in ./support/ and its subdirectories. Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f} RSpec.configure do |config| config.expect_with :rspec do |c| c.syntax = :expect end config.before(:all) do # compile all js files begin Dir["#{File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))}/**/*.coffee"].each do |coffee| File.open(coffee.gsub(/\.coffee$/, ""), 'w') do |f| f.write(CoffeeScript.compile(File.read(coffee)).lstrip) end end # compile all js files end draw_routes end config.before :each do evaljs("var window = this;", true) def inspectify(value) case value when V8::Array value.map do |v| inspectify(v) end when V8::Object value.to_h.map do |k,v| [k, inspectify(v)] end.to_h when String, nil, Fixnum, FalseClass, TrueClass value else raise "wtf #{value.class}?" end end jscontext[:log] = lambda do |context, value| puts inspectify(value).to_json end end end js-routes-1.3.3/spec/dummy/0000755000004100000410000000000013124471555015575 5ustar www-datawww-datajs-routes-1.3.3/spec/dummy/config/0000755000004100000410000000000013124471555017042 5ustar www-datawww-datajs-routes-1.3.3/spec/dummy/config/routes.rb0000644000004100000410000000463513124471555020720 0ustar www-datawww-dataApp.routes.draw do resource "3df1b2d050ae5a96eac8565c9daef37a" resource "341f9e69e3db1c344de2fc6551885711" resource "0e1bcb2dc1ce4d80ec15cae9140fb99a" resource "15b91c612530bfc69c70d121c8713da4" resource "49e12936168a64dce4d4ec148104fb5a" resource "d878104611f88952aba49965c1d2d573" resource "0e94bfc3c8aaee5ea09579fe73cbdaff" resource "e1c2dd2ea9c63b380eb0947a0e1f49aa" resource "587c6e26ad7f9a6aa09f81add77b16f5" resource "8e00bfffebe0c874d6dad1c7b8c7cd6b" resource "394482d3515e7e49989a8496afa7d367" resource "4ab9c701622cba87eae50795564abe1c" resource "af4b4a2ea501fefbdb8367eb108b2e14" resource "116d17a93932a9a3e5bd2750665582f9" resource "315f0a62063288cd56373c8a00870596" resource "d5357ec6df4589f81ca8689cf0231667" resource "560a3b8cf807e873843cd889400cd52b" resource "361de6041f545e67db1aeaa6206c8ac7" resource "28b0a54de4a0884386f1e324edc13194" resource "ab77f21a956d956295187806cdf38cd1" resource "0b8a362fd486247fb7c41898709b9815" resource "5efa0a96733bc027b3309ffb54d1d1d0" resource "70a3ee535c59fcf59c58b6d39178833c" resource "5095fc05868c673ce450524f78cd28d3" resource "79b994cfbc79432d644a3b83804f4924" resource "e25125c477cd451fd74a76eaaebc9165" resource "672fbfb432687e2fee7d0e799cc10ea4" resource "2eb8350243305659082eb92b2e5b702c" resource "08c9973b624e10b10dc7235659c81346" resource "fee0d4b123529a2c652bef0ec0116ef2" resource "8422445d2aa176b7733473164c461a2e" resource "c24b8252b235431ca3df21a6ac119062" resource "c08c66c7fc40e9937ff84a86f6c6d18a" resource "964851acca72064d861188150e848d55" resource "d02927a4fd37b37c03dbad5d3c7a4753" resource "2a69df680ff9bd8d3855d9ce5a4e51f7" resource "d8daed677f9a9a6926005afbdeebcf73" resource "83d4db872f5f148e9ead108d483fec78" resource "09f9fb4250595d26f4149b76fcfa957d" resource "956cdb4d3cbf36bb9ccb7c7fcc36a602" resource "02816449a6c929f55f8bad958f25d25a" resource "2dd7ae38bd72f7e8b26aafb5f002d634" resource "c7c9aaa3f7131f1e7dbc9325b3426d3e" resource "7556e7d17c2a26acbad7d5fa86e6e640" resource "d03081ef427a227a808c708282fdc86b" resource "8f610d21e6e499c1eea98ca08191c05f" resource "b6b412ae8a369f6bfc7f312245eacc8c" resource "e9bcda8b00879c49bd7f05afee59a28e" resource "6e89f4baddd4044b42be7c2d3b382567" resource "5959c376d15a609f2e74f4f351d0a565" resource "3b7e418511c305c78f2d2c292a3a1289" resource "87acf6bf6e8191ff8900f420b33d5268" resource "648a9b17078423f29f42aa2ecac1cc7d" end js-routes-1.3.3/spec/dummy/app/0000755000004100000410000000000013124471555016355 5ustar www-datawww-datajs-routes-1.3.3/spec/dummy/app/assets/0000755000004100000410000000000013124471555017657 5ustar www-datawww-datajs-routes-1.3.3/spec/dummy/app/assets/javascripts/0000755000004100000410000000000013124471555022210 5ustar www-datawww-datajs-routes-1.3.3/spec/dummy/app/assets/javascripts/.gitkeep0000644000004100000410000000000013124471555023627 0ustar www-datawww-datajs-routes-1.3.3/spec/support/0000755000004100000410000000000013124471555016156 5ustar www-datawww-datajs-routes-1.3.3/spec/support/routes.rb0000644000004100000410000000377613124471555020041 0ustar www-datawww-datadef draw_routes BlogEngine::Engine.routes.draw do root to: "application#index" resources :posts end App.routes.draw do get 'support(/page/:page)', to: BlogEngine::Engine, as: 'support' resources :inboxes do resources :messages do resources :attachments end end root :to => "inboxes#index" namespace :admin do resources :users end scope "/returns/:return" do resources :objects end resources :returns scope "(/optional/:optional_id)" do resources :things end get "(/sep1/:first_optional)/sep2/:second_required/sep3/:third_required(/:forth_optional)", as: :thing_deep, controller: :things, action: :show if Rails.version < "5.0.0" get "/:controller(/:action(/:id))" => "classic#classic", :as => :classic end get "/other_optional/(:optional_id)" => "foo#foo", :as => :foo get '/other_optional(/*optional_id)' => 'foo#foo', :as => :foo_all get 'books/*section/:title' => 'books#show', :as => :book get 'books/:title/*section' => 'books#show', :as => :book_title mount BlogEngine::Engine => "/blog", :as => :blog_app get '/no_format' => "foo#foo", :format => false, :as => :no_format get '/json_only' => "foo#foo", :format => true, :constraints => {:format => /json/}, :as => :json_only get '/привет' => "foo#foo", :as => :hello get '(/o/:organization)/search/:q' => "foo#foo", as: :search resources :sessions, :only => [:new, :create, :destroy], :protocol => 'https' get '/' => 'sso#login', host: 'sso.example.com', as: :sso resources :portals, :port => 8080 get '/with_defaults' => 'foo#foo', defaults: { bar: 'tested', format: :json }, format: :true namespace :api, format: true, defaults: {format: 'json'} do get "/purchases" => "purchases#index" end resources :budgies do get "descendents" end namespace :backend, path: '', constraints: {subdomain: 'backend'} do root to: 'backend#index' end end end js-routes-1.3.3/.travis.yml0000644000004100000410000000173213124471555015624 0ustar www-datawww-datalanguage: ruby cache: bundler before_install: - gem install bundler # need for jruby and ruby-head rvm: - 2.0 - 2.1 - 2.2.5 - 2.3.1 - jruby-19mode - ruby-head - jruby-head gemfile: - gemfiles/rails32.gemfile - gemfiles/rails40.gemfile - gemfiles/rails40_sprockets3.gemfile - gemfiles/rails41.gemfile - gemfiles/rails41_sprockets3.gemfile - gemfiles/rails42.gemfile - gemfiles/rails42_sprockets3.gemfile - gemfiles/rails50.gemfile - gemfiles/rails50_sprockets3.gemfile sudo: false notifications: email: - agresso@gmail.com branches: only: - master matrix: allow_failures: - rvm: jruby-19mode - rvm: ruby-head - rvm: jruby-head - gemfile: gemfiles/rails50.gemfile exclude: - rvm: 2.0 gemfile: gemfiles/rails50.gemfile - rvm: 2.0 gemfile: gemfiles/rails50_sprockets3.gemfile - rvm: 2.1 gemfile: gemfiles/rails50.gemfile - rvm: 2.1 gemfile: gemfiles/rails50_sprockets3.gemfile js-routes-1.3.3/lib/0000755000004100000410000000000013124471555014256 5ustar www-datawww-datajs-routes-1.3.3/lib/js_routes.rb0000644000004100000410000002037413124471555016626 0ustar www-datawww-datarequire 'uri' require 'js_routes/engine' if defined?(Rails) require 'js_routes/version' class JsRoutes # # OPTIONS # DEFAULT_PATH = File.join('app','assets','javascripts','routes.js') DEFAULTS = { namespace: "Routes", exclude: [], include: //, file: DEFAULT_PATH, prefix: nil, url_links: false, camel_case: false, default_url_options: {}, compact: false, serializer: nil, special_options_key: "_options", } NODE_TYPES = { GROUP: 1, CAT: 2, SYMBOL: 3, OR: 4, STAR: 5, LITERAL: 6, SLASH: 7, DOT: 8 } LAST_OPTIONS_KEY = "options".freeze FILTERED_DEFAULT_PARTS = [:controller, :action, :subdomain] URL_OPTIONS = [:protocol, :domain, :host, :port, :subdomain] class Options < Struct.new(*DEFAULTS.keys) def to_hash Hash[*members.zip(values).flatten(1)].symbolize_keys end end # # API # class << self def setup(&block) options.tap(&block) if block end def options @options ||= Options.new.tap do |opts| DEFAULTS.each_pair {|k,v| opts[k] = v} end end def generate(opts = {}) new(opts).generate end def generate!(file_name=nil, opts = {}) if file_name.is_a?(Hash) opts = file_name file_name = opts[:file] end new(opts).generate!(file_name) end # Under rails 3.1.1 and higher, perform a check to ensure that the # full environment will be available during asset compilation. # This is required to ensure routes are loaded. def assert_usable_configuration! if 3 == Rails::VERSION::MAJOR && !Rails.application.config.assets.initialize_on_precompile raise("Cannot precompile js-routes unless environment is initialized. Please set config.assets.initialize_on_precompile to true.") end true end def json(string) ActiveSupport::JSON.encode(string) end end # # Implementation # def initialize(options = {}) @options = self.class.options.to_hash.merge(options) end def generate # Ensure routes are loaded. If they're not, load them. if named_routes.to_a.empty? && application.respond_to?(:reload_routes!) application.reload_routes! end { "GEM_VERSION" => JsRoutes::VERSION, "APP_CLASS" => application.class.to_s, "NAMESPACE" => @options[:namespace], "DEFAULT_URL_OPTIONS" => json(@options[:default_url_options].merge(deprecate_url_options)), "PREFIX" => @options[:prefix] || Rails.application.config.relative_url_root || "", "NODE_TYPES" => json(NODE_TYPES), "SERIALIZER" => @options[:serializer] || json(nil), "ROUTES" => js_routes, "SPECIAL_OPTIONS_KEY" => @options[:special_options_key].to_s, "DEPRECATED_BEHAVIOR" => Rails.version < "4", }.inject(File.read(File.dirname(__FILE__) + "/routes.js")) do |js, (key, value)| js.gsub!(key, value.to_s) end end def deprecate_url_options result = {} if @options.key?(:default_format) warn("default_format option is deprecated. Use default_url_options = { format: } instead") result.merge!( format: @options[:default_format] ) end if @options[:url_links].is_a?(String) ActiveSupport::Deprecation.warn('js-routes url_links config value must be a boolean. Use default_url_options for specifying a default host.') raise "invalid URL format in url_links (ex: http[s]://example.com)" if @options[:url_links].match(URI::Parser.new.make_regexp(%w(http https))).nil? uri = URI.parse(@options[:url_links]) default_port = uri.scheme == "https" ? 443 : 80 port = uri.port == default_port ? nil : uri.port result.merge!( host: uri.host, port: port, protocol: uri.scheme, ) end result end def generate!(file_name = nil) # Some libraries like Devise do not yet loaded their routes so we will wait # until initialization process finish # https://github.com/railsware/js-routes/issues/7 Rails.configuration.after_initialize do file_name ||= self.class.options['file'] File.open(Rails.root.join(file_name || DEFAULT_PATH), 'w') do |f| f.write generate end end end protected def application @options[:application] || Rails.application end def named_routes application.routes.named_routes.to_a end def js_routes js_routes = named_routes.sort_by(&:first).flat_map do |_, route| [build_route_if_match(route)] + mounted_app_routes(route) end.compact "{\n" + js_routes.join(",\n") + "}\n" end def mounted_app_routes(route) rails_engine_app = get_app_from_route(route) if rails_engine_app.respond_to?(:superclass) && rails_engine_app.superclass == Rails::Engine && !route.path.anchored rails_engine_app.routes.named_routes.map do |_, engine_route| build_route_if_match(engine_route, route) end else [] end end def get_app_from_route(route) # rails engine in Rails 4.2 use additional ActionDispatch::Routing::Mapper::Constraints, which contain app if route.app.respond_to?(:app) && route.app.respond_to?(:constraints) route.app.app else route.app end end def build_route_if_match(route, parent_route=nil) if any_match?(route, parent_route, @options[:exclude]) || !any_match?(route, parent_route, @options[:include]) nil else build_js(route, parent_route) end end def any_match?(route, parent_route, matchers) full_route = [parent_route.try(:name), route.name].compact.join('_') matchers = Array(matchers) matchers.any? {|regex| full_route =~ regex} end def build_js(route, parent_route) name = [parent_route.try(:name), route.name].compact route_name = generate_route_name(name, (:path unless @options[:compact])) parent_spec = parent_route.try(:path).try(:spec) route_arguments = route_js_arguments(route, parent_spec) url_link = generate_url_link(name, route_name, route_arguments, route) _ = <<-JS.strip! // #{name.join('.')} => #{parent_spec}#{route.path.spec} // function(#{build_params(route.required_parts)}) #{route_name}: Utils.route(#{route_arguments})#{",\n" + url_link if url_link.length > 0} JS end def route_js_arguments(route, parent_spec) required_parts = route.required_parts parts_table = route.parts.each_with_object({}) do |part, hash| hash[part] = required_parts.include?(part) end default_options = route.defaults.select do |part, _| FILTERED_DEFAULT_PARTS.exclude?(part) && URL_OPTIONS.include?(part) || parts_table[part] end [ # JS objects don't preserve the order of properties which is crucial, # so array is a better choice. parts_table.to_a, default_options, serialize(route.path.spec, parent_spec) ].map do |argument| json(argument) end.join(", ") end def generate_url_link(name, route_name, route_arguments, route) return "" unless @options[:url_links] <<-JS.strip! #{generate_route_name(name, :url)}: Utils.route(#{route_arguments}, true) JS end def generate_route_name(name, suffix) route_name = name.join('_') route_name << "_#{ suffix }" if suffix @options[:camel_case] ? route_name.camelize(:lower) : route_name end def json(string) self.class.json(string) end def build_params(required_parts) params = required_parts + [LAST_OPTIONS_KEY] params.join(", ") end # This function serializes Journey route into JSON structure # We do not use Hash for human readable serialization # And preffer Array serialization because it is shorter. # Routes.js file will be smaller. def serialize(spec, parent_spec=nil) return nil unless spec return spec.tr(':', '') if spec.is_a?(String) result = serialize_spec(spec, parent_spec) if parent_spec && result[1].is_a?(String) result = [ # We encode node symbols as integer # to reduce the routes.js file size NODE_TYPES[:CAT], serialize_spec(parent_spec), result ] end result end def serialize_spec(spec, parent_spec=nil) [ NODE_TYPES[spec.type], serialize(spec.left, parent_spec), spec.respond_to?(:right) && serialize(spec.right) ] end end js-routes-1.3.3/lib/js_routes/0000755000004100000410000000000013124471555016273 5ustar www-datawww-datajs-routes-1.3.3/lib/js_routes/engine.rb0000644000004100000410000000471313124471555020072 0ustar www-datawww-dataclass JsRoutesSprocketsExtension def initialize(filename, &block) @filename = filename @source = block.call end def render(context, empty_hash_wtf) self.class.run(@filename, @source, context) end def self.run(filename, source, context) if context.logical_path == 'js-routes' routes = Rails.root.join('config', 'routes.rb').to_s context.depend_on(routes) end source end def self.call(input) filename = input[:filename] source = input[:data] context = input[:environment].context_class.new(input) result = run(filename, source, context) context.metadata.merge(data: result) end end class Engine < ::Rails::Engine require 'sprockets/version' v2 = Gem::Dependency.new('', ' ~> 2') v3 = Gem::Dependency.new('', ' >= 3' ,' < 3.7') v37 = Gem::Dependency.new('', ' >= 3.7') sprockets_version = Gem::Version.new(::Sprockets::VERSION).release initializer_args = case sprockets_version when -> (v) { v2.match?('', v) } { after: "sprockets.environment" } when -> (v) { v3.match?('', v) || v37.match?('', v) } { after: :engines_blank_point, before: :finisher_hook } else raise StandardError, "Sprockets version #{sprockets_version} is not supported" end is_running_rails = defined?(Rails) && Rails.respond_to?(:version) is_running_rails_32 = is_running_rails && Rails.version.match(/3\.2/) initializer 'js-routes.dependent_on_routes', initializer_args do case sprockets_version when -> (v) { v2.match?('', v) }, -> (v) { v3.match?('', v) }, -> (v) { v37.match?('', v) } # It seems rails 3.2 is not working if # `Rails.application.config.assets.configure` is used for # registering preprocessor if is_running_rails_32 Rails.application.assets.register_preprocessor( "application/javascript", JsRoutesSprocketsExtension, ) else # Other rails version, assumed newer Rails.application.config.assets.configure do |config| config.register_preprocessor( "application/javascript", JsRoutesSprocketsExtension, ) end end else raise StandardError, "Sprockets version #{sprockets_version} is not supported" end end end js-routes-1.3.3/lib/js_routes/version.rb0000644000004100000410000000004713124471555020306 0ustar www-datawww-dataclass JsRoutes VERSION = "1.3.3" end js-routes-1.3.3/lib/tasks/0000755000004100000410000000000013124471555015403 5ustar www-datawww-datajs-routes-1.3.3/lib/tasks/js_routes.rake0000644000004100000410000000030113124471555020256 0ustar www-datawww-datanamespace :js do desc "Make a js file that will have functions that will return restful routes/urls." task routes: :environment do require "js-routes" JsRoutes.generate! end end js-routes-1.3.3/lib/routes.js.coffee0000644000004100000410000002762713124471555017401 0ustar www-datawww-data### File generated by js-routes GEM_VERSION Based on Rails routes of APP_CLASS ### # root is this root = (exports ? this) ParameterMissing = (@message) -> # ParameterMissing:: = new Error() defaults = prefix: "PREFIX" default_url_options: DEFAULT_URL_OPTIONS NodeTypes = NODE_TYPES SpecialOptionsKey = "SPECIAL_OPTIONS_KEY" DeprecatedBehavior = DEPRECATED_BEHAVIOR ReservedOptions = [ 'anchor' 'trailing_slash' 'host' 'port' 'protocol' ] Utils = default_serializer: (object, prefix = null) -> return "" unless object? if !prefix and !(@get_object_type(object) is "object") throw new Error("Url parameters should be a javascript hash") s = [] switch @get_object_type(object) when "array" for element, i in object s.push @default_serializer(element, prefix + "[]") when "object" for own key, prop of object if !prop? and prefix? prop = "" if prop? key = "#{prefix}[#{key}]" if prefix? s.push @default_serializer(prop, key) else if object? s.push "#{encodeURIComponent(prefix.toString())}=#{encodeURIComponent(object.toString())}" return "" unless s.length s.join("&") custom_serializer: SERIALIZER serialize: (object) -> if @custom_serializer? and @get_object_type(@custom_serializer) is "function" @custom_serializer(object) else @default_serializer(object) clean_path: (path) -> path = path.split("://") last_index = path.length - 1 path[last_index] = path[last_index].replace(/\/+/g, "/") path.join "://" extract_options: (number_of_params, args) -> last_el = args[args.length - 1] if (args.length > number_of_params and last_el == undefined) or (last_el? and "object" is @get_object_type(last_el) and !@looks_like_serialized_model(last_el)) options = args.pop() || {} delete options[SpecialOptionsKey] options else {} looks_like_serialized_model: (object) -> !object[SpecialOptionsKey] and ("id" of object or "to_param" of object) path_identifier: (object) -> return "0" if object is 0 # null, undefined, false or '' return "" unless object property = object if @get_object_type(object) is "object" if "to_param" of object throw new ParameterMissing("Route parameter missing: to_param") unless object.to_param? property = object.to_param else if "id" of object throw new ParameterMissing("Route parameter missing: id") unless object.id? property = object.id else property = object property = property.call(object) if @get_object_type(property) is "function" property.toString() clone: (obj) -> return obj if !obj? or "object" isnt @get_object_type(obj) copy = obj.constructor() copy[key] = attr for own key, attr of obj copy merge: (xs...) -> tap = (o, fn) -> fn(o); o if xs?.length > 0 tap {}, (m) -> m[k] = v for k, v of x for x in xs normalize_options: (parts, required_parts, default_options, actual_parameters) -> options = @extract_options(parts.length, actual_parameters) if actual_parameters.length > parts.length throw new Error("Too many parameters provided for path") use_all_parts = DeprecatedBehavior or actual_parameters.length > required_parts.length parts_options = {} for own key of options use_all_parts = true if @indexOf(parts, key) >= 0 parts_options[key] = value options = @merge(defaults.default_url_options, default_options, options) result = {} url_parameters = {} result['url_parameters'] = url_parameters for own key, value of options if @indexOf(ReservedOptions, key) >= 0 result[key] = value else url_parameters[key] = value route_parts = if use_all_parts then parts else required_parts i = 0 for part in route_parts when i < actual_parameters.length unless parts_options.hasOwnProperty(part) url_parameters[part] = actual_parameters[i] ++i result build_route: (parts, required_parts, default_options, route, full_url, args) -> args = Array::slice.call(args) options = @normalize_options(parts, required_parts, default_options, args) parameters = options['url_parameters'] # path result = "#{@get_prefix()}#{@visit(route, parameters)}" url = Utils.clean_path(result) # set trailing_slash url = url.replace(/(.*?)[\/]?$/, "$1/") if options['trailing_slash'] is true # set additional url params if (url_params = @serialize(parameters)).length url += "?#{url_params}" # set anchor url += if options.anchor then "##{options.anchor}" else "" if full_url url = @route_url(options) + url url # # This function is JavaScript impelementation of the # Journey::Visitors::Formatter that builds route by given parameters # from route binary tree. # Binary tree is serialized in the following way: # [node type, left node, right node ] # # @param {Boolean} optional Marks the currently visited branch as optional. # If set to `true`, this method will not throw when encountering # a missing parameter (used in recursive calls). # visit: (route, parameters, optional = false) -> [type, left, right] = route switch type when NodeTypes.GROUP @visit left, parameters, true when NodeTypes.STAR @visit_globbing left, parameters, true when NodeTypes.LITERAL, NodeTypes.SLASH, NodeTypes.DOT left when NodeTypes.CAT left_part = @visit(left, parameters, optional) right_part = @visit(right, parameters, optional) if optional and ((@is_optional_node(left[0]) and not left_part) or ((@is_optional_node(right[0])) and not right_part)) return "" "#{left_part}#{right_part}" when NodeTypes.SYMBOL value = parameters[left] if value? delete parameters[left] return @path_identifier(value) if optional "" # missing parameter else throw new ParameterMissing("Route parameter missing: #{left}") # # I don't know what is this node type # Please send your PR if you do # # when NodeTypes.OR: else throw new Error("Unknown Rails node type") is_optional_node: (node) -> @indexOf([NodeTypes.STAR, NodeTypes.SYMBOL, NodeTypes.CAT], node) >= 0 # # This method build spec for route # build_path_spec: (route, wildcard=false) -> [type, left, right] = route switch type when NodeTypes.GROUP "(#{@build_path_spec(left)})" when NodeTypes.CAT "#{@build_path_spec(left)}#{@build_path_spec(right)}" when NodeTypes.STAR @build_path_spec(left, true) when NodeTypes.SYMBOL if wildcard is true "#{if left[0] is '*' then '' else '*'}#{left}" else ":#{left}" when NodeTypes.SLASH, NodeTypes.DOT, NodeTypes.LITERAL left # Not sure about this one # when NodeTypes.OR else throw new Error("Unknown Rails node type") # # This method convert value for globbing in right value for rails route # visit_globbing: (route, parameters, optional) -> [type, left, right] = route # fix for rails 4 globbing route[1] = left = left.replace(/^\*/i, "") if left.replace(/^\*/i, "") isnt left value = parameters[left] return @visit(route, parameters, optional) unless value? parameters[left] = switch @get_object_type(value) when "array" value.join("/") else value @visit route, parameters, optional # # This method check and return prefix from options # get_prefix: -> prefix = defaults.prefix prefix = (if prefix.match("/$") then prefix else "#{prefix}/") if prefix isnt "" prefix # # route function: create route path function and add spec to it # route: (parts_table, default_options, route_spec, full_url) -> required_parts = [] parts = [] for [part, required] in parts_table parts.push(part) required_parts.push(part) if required path_fn = -> Utils.build_route( parts, required_parts, default_options, route_spec, full_url, arguments ) path_fn.required_params = required_parts path_fn.toString = -> Utils.build_path_spec(route_spec) path_fn route_url: (route_defaults) -> return route_defaults if typeof route_defaults == 'string' protocol = route_defaults.protocol || Utils.current_protocol() hostname = route_defaults.host || window.location.hostname port = route_defaults.port || (Utils.current_port() unless route_defaults.host) port = if port then ":#{port}" else '' protocol + "://" + hostname + port has_location: -> typeof window != 'undefined' && typeof window.location != 'undefined' current_host: -> if @has_location() then window.location.hostname else null current_protocol: () -> if @has_location() && window.location.protocol != '' # location.protocol includes the colon character window.location.protocol.replace(/:$/, '') else 'http' current_port: () -> if @has_location() && window.location.port != '' window.location.port else '' # # This is helper method to define object type. # The typeof operator is probably the biggest design flaw of JavaScript, simply because it's basically completely broken. # # Value Class Type # ------------------------------------- # "foo" String string # new String("foo") String object # 1.2 Number number # new Number(1.2) Number object # true Boolean boolean # new Boolean(true) Boolean object # new Date() Date object # new Error() Error object # [1,2,3] Array object # new Array(1, 2, 3) Array object # new Function("") Function function # /abc/g RegExp object # new RegExp("meow") RegExp object # {} Object object # new Object() Object object # # What is why I use Object.prototype.toString() to know better type of variable. Or use jQuery.type, if it available. # _classToTypeCache used for perfomance cache of types map (underscore at the beginning mean private method - of course it doesn't realy private). # _classToTypeCache: null _classToType: -> return @_classToTypeCache if @_classToTypeCache? @_classToTypeCache = {} for name in "Boolean Number String Function Array Date RegExp Object Error".split(" ") @_classToTypeCache["[object #{name}]"] = name.toLowerCase() @_classToTypeCache get_object_type: (obj) -> return root.jQuery.type(obj) if root.jQuery and root.jQuery.type? return "#{obj}" unless obj? (if typeof obj is "object" or typeof obj is "function" then @_classToType()[Object::toString.call(obj)] or "object" else typeof obj) # indexOf helper indexOf: (array, element) -> if Array::indexOf then array.indexOf(element) else @indexOfImplementation(array, element) indexOfImplementation: (array, element) -> result = -1 (result = i for el, i in array when el is element) result # globalJsObject createGlobalJsRoutesObject = -> # namespace function, private namespace = (mainRoot, namespaceString) -> parts = (if namespaceString then namespaceString.split(".") else []) return unless parts.length current = parts.shift() mainRoot[current] = mainRoot[current] or {} namespace mainRoot[current], parts.join(".") # object namespace(root, "NAMESPACE") root.NAMESPACE = ROUTES root.NAMESPACE.options = defaults root.NAMESPACE.default_serializer = (object, prefix) -> Utils.default_serializer(object, prefix) root.NAMESPACE # Set up Routes appropriately for the environment. if typeof define is "function" and define.amd # AMD define [], -> createGlobalJsRoutesObject() else # Browser globals createGlobalJsRoutesObject() js-routes-1.3.3/lib/js-routes.rb0000644000004100000410000000002413124471555016532 0ustar www-datawww-datarequire 'js_routes' js-routes-1.3.3/lib/routes.js0000644000004100000410000003531613124471555016145 0ustar www-datawww-data/* File generated by js-routes GEM_VERSION Based on Rails routes of APP_CLASS */ (function() { var DeprecatedBehavior, NodeTypes, ParameterMissing, ReservedOptions, SpecialOptionsKey, Utils, createGlobalJsRoutesObject, defaults, root, hasProp = {}.hasOwnProperty, slice = [].slice; root = typeof exports !== "undefined" && exports !== null ? exports : this; ParameterMissing = function(message) { this.message = message; }; ParameterMissing.prototype = new Error(); defaults = { prefix: "PREFIX", default_url_options: DEFAULT_URL_OPTIONS }; NodeTypes = NODE_TYPES; SpecialOptionsKey = "SPECIAL_OPTIONS_KEY"; DeprecatedBehavior = DEPRECATED_BEHAVIOR; ReservedOptions = ['anchor', 'trailing_slash', 'host', 'port', 'protocol']; Utils = { default_serializer: function(object, prefix) { var element, i, j, key, len, prop, s; if (prefix == null) { prefix = null; } if (object == null) { return ""; } if (!prefix && !(this.get_object_type(object) === "object")) { throw new Error("Url parameters should be a javascript hash"); } s = []; switch (this.get_object_type(object)) { case "array": for (i = j = 0, len = object.length; j < len; i = ++j) { element = object[i]; s.push(this.default_serializer(element, prefix + "[]")); } break; case "object": for (key in object) { if (!hasProp.call(object, key)) continue; prop = object[key]; if ((prop == null) && (prefix != null)) { prop = ""; } if (prop != null) { if (prefix != null) { key = prefix + "[" + key + "]"; } s.push(this.default_serializer(prop, key)); } } break; default: if (object != null) { s.push((encodeURIComponent(prefix.toString())) + "=" + (encodeURIComponent(object.toString()))); } } if (!s.length) { return ""; } return s.join("&"); }, custom_serializer: SERIALIZER, serialize: function(object) { if ((this.custom_serializer != null) && this.get_object_type(this.custom_serializer) === "function") { return this.custom_serializer(object); } else { return this.default_serializer(object); } }, clean_path: function(path) { var last_index; path = path.split("://"); last_index = path.length - 1; path[last_index] = path[last_index].replace(/\/+/g, "/"); return path.join("://"); }, extract_options: function(number_of_params, args) { var last_el, options; last_el = args[args.length - 1]; 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))) { options = args.pop() || {}; delete options[SpecialOptionsKey]; return options; } else { return {}; } }, looks_like_serialized_model: function(object) { return !object[SpecialOptionsKey] && ("id" in object || "to_param" in object); }, path_identifier: function(object) { var property; if (object === 0) { return "0"; } if (!object) { return ""; } property = object; if (this.get_object_type(object) === "object") { if ("to_param" in object) { if (object.to_param == null) { throw new ParameterMissing("Route parameter missing: to_param"); } property = object.to_param; } else if ("id" in object) { if (object.id == null) { throw new ParameterMissing("Route parameter missing: id"); } property = object.id; } else { property = object; } if (this.get_object_type(property) === "function") { property = property.call(object); } } return property.toString(); }, clone: function(obj) { var attr, copy, key; if ((obj == null) || "object" !== this.get_object_type(obj)) { return obj; } copy = obj.constructor(); for (key in obj) { if (!hasProp.call(obj, key)) continue; attr = obj[key]; copy[key] = attr; } return copy; }, merge: function() { var tap, xs; xs = 1 <= arguments.length ? slice.call(arguments, 0) : []; tap = function(o, fn) { fn(o); return o; }; if ((xs != null ? xs.length : void 0) > 0) { return tap({}, function(m) { var j, k, len, results, v, x; results = []; for (j = 0, len = xs.length; j < len; j++) { x = xs[j]; results.push((function() { var results1; results1 = []; for (k in x) { v = x[k]; results1.push(m[k] = v); } return results1; })()); } return results; }); } }, normalize_options: function(parts, required_parts, default_options, actual_parameters) { var i, j, key, len, options, part, parts_options, result, route_parts, url_parameters, use_all_parts, value; options = this.extract_options(parts.length, actual_parameters); if (actual_parameters.length > parts.length) { throw new Error("Too many parameters provided for path"); } use_all_parts = DeprecatedBehavior || actual_parameters.length > required_parts.length; parts_options = {}; for (key in options) { if (!hasProp.call(options, key)) continue; use_all_parts = true; if (this.indexOf(parts, key) >= 0) { parts_options[key] = value; } } options = this.merge(defaults.default_url_options, default_options, options); result = {}; url_parameters = {}; result['url_parameters'] = url_parameters; for (key in options) { if (!hasProp.call(options, key)) continue; value = options[key]; if (this.indexOf(ReservedOptions, key) >= 0) { result[key] = value; } else { url_parameters[key] = value; } } route_parts = use_all_parts ? parts : required_parts; i = 0; for (j = 0, len = route_parts.length; j < len; j++) { part = route_parts[j]; if (i < actual_parameters.length) { if (!parts_options.hasOwnProperty(part)) { url_parameters[part] = actual_parameters[i]; ++i; } } } return result; }, build_route: function(parts, required_parts, default_options, route, full_url, args) { var options, parameters, result, url, url_params; args = Array.prototype.slice.call(args); options = this.normalize_options(parts, required_parts, default_options, args); parameters = options['url_parameters']; result = "" + (this.get_prefix()) + (this.visit(route, parameters)); url = Utils.clean_path(result); if (options['trailing_slash'] === true) { url = url.replace(/(.*?)[\/]?$/, "$1/"); } if ((url_params = this.serialize(parameters)).length) { url += "?" + url_params; } url += options.anchor ? "#" + options.anchor : ""; if (full_url) { url = this.route_url(options) + url; } return url; }, visit: function(route, parameters, optional) { var left, left_part, right, right_part, type, value; if (optional == null) { optional = false; } type = route[0], left = route[1], right = route[2]; switch (type) { case NodeTypes.GROUP: return this.visit(left, parameters, true); case NodeTypes.STAR: return this.visit_globbing(left, parameters, true); case NodeTypes.LITERAL: case NodeTypes.SLASH: case NodeTypes.DOT: return left; case NodeTypes.CAT: left_part = this.visit(left, parameters, optional); right_part = this.visit(right, parameters, optional); if (optional && ((this.is_optional_node(left[0]) && !left_part) || ((this.is_optional_node(right[0])) && !right_part))) { return ""; } return "" + left_part + right_part; case NodeTypes.SYMBOL: value = parameters[left]; if (value != null) { delete parameters[left]; return this.path_identifier(value); } if (optional) { return ""; } else { throw new ParameterMissing("Route parameter missing: " + left); } break; default: throw new Error("Unknown Rails node type"); } }, is_optional_node: function(node) { return this.indexOf([NodeTypes.STAR, NodeTypes.SYMBOL, NodeTypes.CAT], node) >= 0; }, build_path_spec: function(route, wildcard) { var left, right, type; if (wildcard == null) { wildcard = false; } type = route[0], left = route[1], right = route[2]; switch (type) { case NodeTypes.GROUP: return "(" + (this.build_path_spec(left)) + ")"; case NodeTypes.CAT: return "" + (this.build_path_spec(left)) + (this.build_path_spec(right)); case NodeTypes.STAR: return this.build_path_spec(left, true); case NodeTypes.SYMBOL: if (wildcard === true) { return "" + (left[0] === '*' ? '' : '*') + left; } else { return ":" + left; } break; case NodeTypes.SLASH: case NodeTypes.DOT: case NodeTypes.LITERAL: return left; default: throw new Error("Unknown Rails node type"); } }, visit_globbing: function(route, parameters, optional) { var left, right, type, value; type = route[0], left = route[1], right = route[2]; if (left.replace(/^\*/i, "") !== left) { route[1] = left = left.replace(/^\*/i, ""); } value = parameters[left]; if (value == null) { return this.visit(route, parameters, optional); } parameters[left] = (function() { switch (this.get_object_type(value)) { case "array": return value.join("/"); default: return value; } }).call(this); return this.visit(route, parameters, optional); }, get_prefix: function() { var prefix; prefix = defaults.prefix; if (prefix !== "") { prefix = (prefix.match("/$") ? prefix : prefix + "/"); } return prefix; }, route: function(parts_table, default_options, route_spec, full_url) { var j, len, part, parts, path_fn, ref, required, required_parts; required_parts = []; parts = []; for (j = 0, len = parts_table.length; j < len; j++) { ref = parts_table[j], part = ref[0], required = ref[1]; parts.push(part); if (required) { required_parts.push(part); } } path_fn = function() { return Utils.build_route(parts, required_parts, default_options, route_spec, full_url, arguments); }; path_fn.required_params = required_parts; path_fn.toString = function() { return Utils.build_path_spec(route_spec); }; return path_fn; }, route_url: function(route_defaults) { var hostname, port, protocol; if (typeof route_defaults === 'string') { return route_defaults; } protocol = route_defaults.protocol || Utils.current_protocol(); hostname = route_defaults.host || window.location.hostname; port = route_defaults.port || (!route_defaults.host ? Utils.current_port() : void 0); port = port ? ":" + port : ''; return protocol + "://" + hostname + port; }, has_location: function() { return typeof window !== 'undefined' && typeof window.location !== 'undefined'; }, current_host: function() { if (this.has_location()) { return window.location.hostname; } else { return null; } }, current_protocol: function() { if (this.has_location() && window.location.protocol !== '') { return window.location.protocol.replace(/:$/, ''); } else { return 'http'; } }, current_port: function() { if (this.has_location() && window.location.port !== '') { return window.location.port; } else { return ''; } }, _classToTypeCache: null, _classToType: function() { var j, len, name, ref; if (this._classToTypeCache != null) { return this._classToTypeCache; } this._classToTypeCache = {}; ref = "Boolean Number String Function Array Date RegExp Object Error".split(" "); for (j = 0, len = ref.length; j < len; j++) { name = ref[j]; this._classToTypeCache["[object " + name + "]"] = name.toLowerCase(); } return this._classToTypeCache; }, get_object_type: function(obj) { if (root.jQuery && (root.jQuery.type != null)) { return root.jQuery.type(obj); } if (obj == null) { return "" + obj; } if (typeof obj === "object" || typeof obj === "function") { return this._classToType()[Object.prototype.toString.call(obj)] || "object"; } else { return typeof obj; } }, indexOf: function(array, element) { if (Array.prototype.indexOf) { return array.indexOf(element); } else { return this.indexOfImplementation(array, element); } }, indexOfImplementation: function(array, element) { var el, i, j, len, result; result = -1; for (i = j = 0, len = array.length; j < len; i = ++j) { el = array[i]; if (el === element) { result = i; } } return result; } }; createGlobalJsRoutesObject = function() { var namespace; namespace = function(mainRoot, namespaceString) { var current, parts; parts = (namespaceString ? namespaceString.split(".") : []); if (!parts.length) { return; } current = parts.shift(); mainRoot[current] = mainRoot[current] || {}; return namespace(mainRoot[current], parts.join(".")); }; namespace(root, "NAMESPACE"); root.NAMESPACE = ROUTES; root.NAMESPACE.options = defaults; root.NAMESPACE.default_serializer = function(object, prefix) { return Utils.default_serializer(object, prefix); }; return root.NAMESPACE; }; if (typeof define === "function" && define.amd) { define([], function() { return createGlobalJsRoutesObject(); }); } else { createGlobalJsRoutesObject(); } }).call(this); js-routes-1.3.3/gemfiles/0000755000004100000410000000000013124471555015303 5ustar www-datawww-datajs-routes-1.3.3/gemfiles/rails41.gemfile0000644000004100000410000000022013124471555020106 0ustar www-datawww-data# This file was generated by Appraisal source "http://rubygems.org" gem "railties", "~> 4.1.1" gem "sprockets", "< 3" gemspec :path => "../" js-routes-1.3.3/gemfiles/rails42_sprockets3.gemfile0000644000004100000410000000025313124471555022275 0ustar www-datawww-data# This file was generated by Appraisal source "http://rubygems.org" gem "railties", "~> 4.2.1" gem "sprockets", "~> 3.0" gem "nokogiri", "< 1.7" gemspec :path => "../" js-routes-1.3.3/gemfiles/rails41_sprockets3.gemfile0000644000004100000410000000022313124471555022271 0ustar www-datawww-data# This file was generated by Appraisal source "http://rubygems.org" gem "railties", "~> 4.1.1" gem "sprockets", "~> 3.0" gemspec :path => "../" js-routes-1.3.3/gemfiles/rails40_sprockets3.gemfile0000644000004100000410000000022313124471555022270 0ustar www-datawww-data# This file was generated by Appraisal source "http://rubygems.org" gem "railties", "~> 4.0.5" gem "sprockets", "~> 3.0" gemspec :path => "../" js-routes-1.3.3/gemfiles/rails50_sprockets3.gemfile0000644000004100000410000000022313124471555022271 0ustar www-datawww-data# This file was generated by Appraisal source "http://rubygems.org" gem "railties", "~> 5.0.0" gem "sprockets", "~> 3.0" gemspec :path => "../" js-routes-1.3.3/gemfiles/rails40.gemfile0000644000004100000410000000022013124471555020105 0ustar www-datawww-data# This file was generated by Appraisal source "http://rubygems.org" gem "railties", "~> 4.0.5" gem "sprockets", "< 3" gemspec :path => "../" js-routes-1.3.3/gemfiles/rails42.gemfile0000644000004100000410000000025013124471555020112 0ustar www-datawww-data# This file was generated by Appraisal source "http://rubygems.org" gem "railties", "~> 4.2.1" gem "sprockets", "< 3" gem "nokogiri", "< 1.7" gemspec :path => "../" js-routes-1.3.3/gemfiles/rails32.gemfile0000644000004100000410000000020713124471555020113 0ustar www-datawww-data# This file was generated by Appraisal source "http://rubygems.org" gem "railties", "~> 3.2.18" gem "tzinfo" gemspec :path => "../" js-routes-1.3.3/gemfiles/rails50.gemfile0000644000004100000410000000022013124471555020106 0ustar www-datawww-data# This file was generated by Appraisal source "http://rubygems.org" gem "railties", "~> 5.0.0" gem "sprockets", "< 3" gemspec :path => "../" js-routes-1.3.3/Readme.md0000644000004100000410000002151213124471555015230 0ustar www-datawww-data# JsRoutes [![Build Status](https://travis-ci.org/railsware/js-routes.svg?branch=master)](https://travis-ci.org/railsware/js-routes) Generates javascript file that defines all Rails named routes as javascript helpers ## Intallation Your Rails Gemfile: ``` ruby gem "js-routes" ``` ### Basic Setup Require js routes file in `application.js` or other bundle ``` js //= require js-routes ``` Also in order to flush asset pipeline cache sometimes you might need to run: ``` sh rake tmp:cache:clear ``` This cache is not flushed on server restart in development environment. **Important:** If routes.js file is not updated after some configuration change you need to run this rake task again. ### Advanced Setup If you need to customize routes file create initializer, like `config/initializers/jsroutes.rb`: ``` ruby JsRoutes.setup do |config| config.option = value end ``` Available options: * `default_url_options` - default parameters used when generating URLs * Note that only specific options are supported at this time. * Example: {:format => "json", :trailing\_slash => true, :protocol => "https", :host => "example.com", :port => 3000} * Default: {} * `exclude` - Array of regexps to exclude from js routes. * Default: [] * The regexp applies only to the name before the `_path` suffix, eg: you want to match exactly `settings_path`, the regexp should be `/^settings$/` * `include` - Array of regexps to include in js routes. * Default: [] * The regexp applies only to the name before the `_path` suffix, eg: you want to match exactly `settings_path`, the regexp should be `/^settings$/` * `namespace` - global object used to access routes. * Supports nested namespace like `MyProject.routes` * Default: `Routes` * `prefix` - String representing a url path to prepend to all paths. * Example: `http://yourdomain.com`. This will cause route helpers to generate full path only. * Default: `Rails.application.config.relative_url_root` * `camel_case` (version >= 0.8.8) - Generate camel case route names. * Default: false * `url_links` (version >= 0.8.9) - Generate `*_url` helpers (in addition to the default `*_path` helpers). * Example: true * Default: false * Note: generated URLs will first use the protocol, host, and port options specified in the route definition. Otherwise, the URL will be based on the option specified in the `default_url_options` config. If no default option has been set, then the URL will fallback to the current URL based on `window.location`. * `compact` (version > 0.9.9) - Remove `_path` suffix in path routes(`*_url` routes stay untouched if they were enabled) * Default: false * Sample route call when option is set to true: Routes.users() => `/users` * `serializer` (version >= 1.1.0) - Puts a JS function here that serializes a Javascript Hash object into URL paramters: `{a: 1, b: 2} => "a=1&b=2"`. * Default: `nil`. Uses built-in serializer * Example: `jQuery.param` - use jQuery's serializer algorithm. You can attach serialize function from your favorite AJAX framework. * Example: `MyApp.custom_serialize` - use completely custom serializer of your application. * `special_options_key` - a special key that helps js-routes to destinguish serialized model from options hash * This option is required because JS doesn't provide a difference between an object and a hash * Default: `_options` * `application` - a key to specify which rails engine you want to generate routes too. * This option allows to only generate routes for a specific rails engine, that is mounted into routes instead of all Rails app routes * Default: `Rails.application` ### Very Advanced Setup In case you need multiple route files for different parts of your application, you have to create the files manually. If your application has an `admin` and an `application` namespace for example: ``` # app/assets/javascripts/admin/routes.js.erb <%= JsRoutes.generate(namespace: "AdminRoutes", include: /admin/) %> # app/assets/javascripts/admin.js.coffee #= require admin/routes ``` ``` # app/assets/javascripts/application/routes.js.erb <%= JsRoutes.generate(namespace: "AppRoutes", exclude: /admin/) %> # app/assets/javascripts/application.js.coffee #= require application/routes ``` In order to generate the routes JS code to a string: ```ruby routes_js = JsRoutes.generate(options) ``` If you want to generate the routes files outside of the asset pipeline, you can use `JsRoutes.generate!`: ``` ruby path = "app/assets/javascripts" JsRoutes.generate!("#{path}/app_routes.js", :namespace => "AppRoutes", :exclude => [/^admin_/, /^api_/]) JsRoutes.generate!("#{path}/adm_routes.js", :namespace => "AdmRoutes", :include => /^admin_/) JsRoutes.generate!("#{path}/api_routes.js", :namespace => "ApiRoutes", :include => /^api_/, :default_url_options => {:format => "json"}) ``` ### Rails relative URL root If you've installed your application in a sub-path or sub-URI of your server instead of at the root, you need to set the `RAILS_RELATIVE_URL_ROOT` environment variable to the correct path prefix for your application when you precompile assets. Eg., if your application's base URL is "https://appl.example.com/Application1", the command to precompile assets would be: ``` RAILS_RELATIVE_URL_ROOT=/Application1 RAILS_ENV=production bundle exec rake assets:precompile ``` The environment variable is only needed for precompilation of assets, at any other time (eg. when assets are compiled on-the-fly as in the development environment) Rails will set the relative URL root correctly on it's own. ## Usage Configuration above will create a nice javascript file with `Routes` object that has all the rails routes available: ``` js Routes.users_path() // => "/users" Routes.user_path(1) // => "/users/1" Routes.user_path(1, {format: 'json'}) // => "/users/1.json" Routes.user_path(1, {anchor: 'profile'}) // => "/users/1#profile" Routes.new_user_project_path(1, {format: 'json'}) // => "/users/1/projects/new.json" Routes.user_project_path(1,2, {q: 'hello', custom: true}) // => "/users/1/projects/2?q=hello&custom=true" Routes.user_project_path(1,2, {hello: ['world', 'mars']}) // => "/users/1/projects/2?hello%5B%5D=world&hello%5B%5D=mars" ``` Using serialized object as route function arguments: ``` js var google = {id: 1, name: "Google"}; Routes.company_path(google) // => "/companies/1" var google = {id: 1, name: "Google", to_param: "google"}; Routes.company_path(google) // => "/companies/google" ``` In order to make routes helpers available globally: ``` js jQuery.extend(window, Routes) ``` ## Get spec of routes and required params Possible to get `spec` of route by function `toString`: ```js Routes.users_path.toString() // => "/users(.:format)" Routes.user_path.toString() // => "/users/:id(.:format)" ``` This function allow to get the same `spec` for route, if you will get string representation of the route function: ```js '' + Routes.users_path // => "/users(.:format)", a string representation of the object '' + Routes.user_path // => "/users/:id(.:format)" ``` Route function also contain inside attribute `required_params` required param names as array: ```js Routes.users_path.required_params // => [] Routes.user_path.required_params // => ['id'] ``` ## Rails Compatibilities JsRoutes ties to be as close as possible to rails behaviour in all aspects of routing API. Please make and issue in case of any incomtibilities found outside of described below. ### Object and Hash distinction issue Sometimes the destinction between JS Hash and Object can not be found by js-routes. In this case you would need to pass a special key to help: ``` js Routes.company_project_path({company_id: 1, id: 2}) // => Not Enough parameters Routes.company_project_path({company_id: 1, id: 2, _options: true}) // => "/companies/1/projects/2" ``` ## What about security? js-routes itself do not have security holes. It makes URLs without access protection more reachable by potential attacker. In order to prevent this use `:exclude` option for sensitive urls like `/admin_/` ## Spork When using Spork and `Spork.trap_method(Rails::Application::RoutesReloader, :reload!)` you should also do: ``` ruby Spork.trap_method(JsRoutes, :generate!) ``` ## JS-Routes and heroku Heroku environment has a specific problems with setup. It is impossible to use asset pipeline in this environment. You should use "Very Advanced Setup" schema in this case. For example create routes.js.erb in assets folder with needed content: ``` erb <%= JsRoutes.generate(options) %> ``` This should just work. ## Advantages over alternatives There are some alternatives available. Most of them has only basic feature and don't reach the level of quality I accept. Advantages of this one are: * Rails 3-5 support * Rich options set * Full rails compatibility * Support Rails `#to_param` convention for seo optimized paths * Well tested #### Thanks to [Contributors](https://github.com/railsware/js-routes/contributors) #### Have fun js-routes-1.3.3/.gitignore0000644000004100000410000000166613124471555015511 0ustar www-datawww-data# rcov generated coverage # rdoc generated rdoc # yard generated doc .yardoc log # bundler .bundle # jeweler generated pkg # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore: # # * Create a file at ~/.gitignore # * Include files you want ignored # * Run: git config --global core.excludesfile ~/.gitignore # # After doing this, these files will be ignored in all your git projects, # saving you from having to 'pollute' every project you touch with them # # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line) # # For MacOS: # #.DS_Store # For TextMate #*.tmproj #tmtags # For emacs: #*~ #\#* #.\#* # For vim: #*.swp # For redcar: #.redcar # For rubinius: #*.rbc .rvmrc .ruby-version Gemfile.lock gemfiles/*.lock .DS_Store /spec/dummy/app/assets/javascripts/routes.js /spec/dummy/logs /spec/dummy/tmp js-routes-1.3.3/Appraisals0000644000004100000410000000057013124471555015534 0ustar www-datawww-dataappraise "rails32" do gem "railties", "~> 3.2.18" gem 'tzinfo' end {rails40: '4.0.5', rails41: '4.1.1', rails42: '4.2.1', rails50: '5.0.0'}.each do |rails, version| appraise "#{rails}" do gem "railties", "~> #{version}" gem "sprockets", "< 3" end appraise "#{rails}-sprockets3" do gem "railties", "~> #{version}" gem "sprockets", "~> 3.0" end endjs-routes-1.3.3/app/0000755000004100000410000000000013124471555014270 5ustar www-datawww-datajs-routes-1.3.3/app/assets/0000755000004100000410000000000013124471555015572 5ustar www-datawww-datajs-routes-1.3.3/app/assets/javascripts/0000755000004100000410000000000013124471555020123 5ustar www-datawww-datajs-routes-1.3.3/app/assets/javascripts/js-routes.js.erb0000644000004100000410000000013113124471555023156 0ustar www-datawww-data<%# encoding: UTF-8 %> <%= JsRoutes.assert_usable_configuration! && JsRoutes.generate %> js-routes-1.3.3/js-routes.gemspec0000644000004100000410000000253213124471555017012 0ustar www-datawww-data# coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'js_routes/version' Gem::Specification.new do |s| s.name = %q{js-routes} s.version = JsRoutes::VERSION s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Bogdan Gusiev"] s.description = %q{Generates javascript file that defines all Rails named routes as javascript helpers} s.email = %q{agresso@gmail.com} s.extra_rdoc_files = [ "LICENSE.txt" ] s.files = `git ls-files`.split("\n") s.homepage = %q{http://github.com/railsware/js-routes} s.licenses = ["MIT"] s.require_paths = ["lib"] s.summary = %q{Brings Rails named routes to javascript} s.add_runtime_dependency(%q, [">= 3.2"]) s.add_runtime_dependency(%q) s.add_development_dependency(%q, [">= 3.0.0"]) s.add_development_dependency(%q, [">= 1.1.0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0.5.2"]) if defined?(JRUBY_VERSION) s.add_development_dependency(%q, [">= 2.0.4"]) else s.add_development_dependency(%q) s.add_development_dependency(%q) s.add_development_dependency(%q, [">= 0.12.1"]) end end js-routes-1.3.3/CHANGELOG.md0000644000004100000410000000613213124471555015323 0ustar www-datawww-data## master ## v1.3.0 * Introduce the special _options key. Fixes #86 ## v1.2.9 * Fixed deprecation varning on Sprockets 3.7 ## v1.2.8 * Bugfix warning on Sprockets 4.0 #202 ## v1.2.7 * Drop support 1.9.3 * Add helper for indexOf, if no native implementation in JS engine * Add sprockets3 compatibility * Bugfix domain defaults to path #197 ## v1.2.6 * Use default prefix from `Rails.application.config.relative_url_root` #186 * Bugfix route globbing with optional fragments bug #191 ## v1.2.5 * Bugfix subdomain default parameter in routes #184 * Bugfix infinite recursion in some specific route sets #183 ## v1.2.4 * Additional bugfixes to support all versions of Sprockets: 2.x and 3.x ## v1.2.3 * Sprockets ~= 3.0 support ## v1.2.2 * Sprockets ~= 3.0 support * Support default parameters specified in route.rb file ## v1.2.1 * Fixes for Rails 5 ## v1.2.0 * Support host, port and protocol inline parameters * Support host, port and protocol parameters given to a route explicitly * Remove all incompatibilities between actiondispatch and js-routes in handling route URLs ## v1.1.2 * Bugfix support nested object null parameters #164 * Bugfix support for nested optional parameters #162 #163 ## v1.1.1 * Bugfix regression in serialisation on blank strings caused by [#155](https://github.com/railsware/js-routes/pull/155/files) ## v1.1.0 * Ensure routes are loaded, prior to generating them [#148](https://github.com/railsware/js-routes/pull/148) * Use `flat_map` rather than `map{...}.flatten` [#149](https://github.com/railsware/js-routes/pull/149) * URL escape routes.rb url to fix bad URI(is not URI?) error [#150](https://github.com/railsware/js-routes/pull/150) * Fix for rails 5 - test rails-edge on travis allowing failure [#151](https://github.com/railsware/js-routes/pull/151) * Adds `serializer` option [#155](https://github.com/railsware/js-routes/pull/155/files) ## v1.0.1 * Support sprockets-3 * Performance optimization of include/exclude options ## v1.0.0 * Add the compact mode [#125](https://github.com/railsware/js-routes/pull/125) * Add support for host, protocol, and port configuration [#137](https://github.com/railsware/js-routes/pull/137) * Routes path specs [#135](https://github.com/railsware/js-routes/pull/135) * Support Rails 4.2 and Ruby 2.2 [#140](https://github.com/railsware/js-routes/pull/140) ## v0.9.9 * Bugfix Rails Engine subapplication route generation when they are nested [#120](https://github.com/railsware/js-routes/pull/120) ## v0.9.8 * Support AMD/Require.js [#111](https://github.com/railsware/js-routes/pull/111) * Support trailing slash [#106](https://github.com/railsware/js-routes/pull/106) ## v0.9.7 * Depend on railties [#97](https://github.com/railsware/js-routes/pull/97) * Fix typeof error for IE [#95](https://github.com/railsware/js-routes/pull/95) * Fix testing on ruby-head [#92](https://github.com/railsware/js-routes/pull/92) * Correct thread safety issue in js-routes generation [#90](https://github.com/railsware/js-routes/pull/90) * Use the `of` operator to detect for `to_param` and `id` in objects [#87](https://github.com/railsware/js-routes/pull/87) js-routes-1.3.3/.document0000644000004100000410000000006713124471555015332 0ustar www-datawww-datalib/**/*.rb bin/* - features/**/*.feature LICENSE.txt