js-routes 2.2.1 → 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 54158654106dece477c1fdf36afa52b504a43b8210c4c8d30f98d41ccd0ef600
4
- data.tar.gz: a67b36754269392839bb6d2e86a20899ec2575437ac9667f10cdd9feb7306185
3
+ metadata.gz: 52db2ffdef9bea714377b9c00e152177b17e40de0fd8ef57ba09a84fee2f206e
4
+ data.tar.gz: 8f899234c70859fee6a7c0486825c12ce501a01052e2b5d9a038f08544ac6df9
5
5
  SHA512:
6
- metadata.gz: 582b6a39a062f6fcfd7b2cb4a57b4fd4573e343f93d5751ef764b7e3617cb7243801caf61ee971224a2c1a41e43a2f51221e5d3a40c12d5db21af98f47467044
7
- data.tar.gz: f54b26ed68ed8ef2a6b4ad5ebf2e0322bfbec7385756a8578b5c11c01eca646d42baa5634d16cef6d16520e3eed4d1b1a37260e4ade943ee568b6b4755153cea
6
+ metadata.gz: e697c45b1908906c40cdc4591f5914dd415226de79a42a8e948f6095e0f09eb5edb5bfb0c5fd61953fde7121d9a025b3472b644ddb17ca2c13cb075c97311000
7
+ data.tar.gz: 7f48edacee6659d4e4b5be0d71b5127f26e473119a8bf13a73c55a7b3c295dbee7fc34b9d3f515725c5871baad319ceb0bb32ed176900845b48a84c786ba3f9c
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## master
2
2
 
3
+ ## v2.2.2.
4
+
5
+ * Fix custom file path [#295](https://github.com/railsware/js-routes/issues/295)
6
+
3
7
  ## v2.2.1
4
8
 
5
9
  * Improve generator to update route files on `assets:precompile` and add them to `.gitignore by default` [#288](https://github.com/railsware/js-routes/issues/288#issuecomment-1012182815)
@@ -0,0 +1,111 @@
1
+ require "pathname"
2
+
3
+ module JsRoutes
4
+ class Configuration
5
+ DEFAULTS = {
6
+ namespace: nil,
7
+ exclude: [],
8
+ include: //,
9
+ file: nil,
10
+ prefix: -> { Rails.application.config.relative_url_root || "" },
11
+ url_links: false,
12
+ camel_case: false,
13
+ default_url_options: {},
14
+ compact: false,
15
+ serializer: nil,
16
+ special_options_key: "_options",
17
+ application: -> { Rails.application },
18
+ module_type: 'ESM',
19
+ documentation: true,
20
+ } #:nodoc:
21
+
22
+ attr_accessor(*DEFAULTS.keys)
23
+
24
+ def initialize(attributes = nil)
25
+ assign(DEFAULTS)
26
+ return unless attributes
27
+ assign(attributes)
28
+ end
29
+
30
+ def assign(attributes = nil, &block)
31
+ if !attributes && !block
32
+ raise "Provide attributes or block"
33
+ end
34
+ tap(&block) if block
35
+ if attributes
36
+ attributes.each do |attribute, value|
37
+ value = value.call if value.is_a?(Proc)
38
+ send(:"#{attribute}=", value)
39
+ end
40
+ end
41
+ normalize_and_verify
42
+ self
43
+ end
44
+
45
+ def [](attribute)
46
+ send(attribute)
47
+ end
48
+
49
+ def merge(attributes)
50
+ clone.assign(attributes)
51
+ end
52
+
53
+ def to_hash
54
+ Hash[*members.zip(values).flatten(1)].symbolize_keys
55
+ end
56
+
57
+ def esm?
58
+ module_type === 'ESM'
59
+ end
60
+
61
+ def dts?
62
+ self.module_type === 'DTS'
63
+ end
64
+
65
+ def modern?
66
+ esm? || dts?
67
+ end
68
+
69
+ def require_esm
70
+ raise "ESM module type is required" unless modern?
71
+ end
72
+
73
+ def source_file
74
+ File.dirname(__FILE__) + "/../" + default_file_name
75
+ end
76
+
77
+ def output_file
78
+ webpacker_dir = pathname('app', 'javascript')
79
+ sprockets_dir = pathname('app','assets','javascripts')
80
+ file_name = file || default_file_name
81
+ sprockets_file = sprockets_dir.join(file_name)
82
+ webpacker_file = webpacker_dir.join(file_name)
83
+ !Dir.exist?(webpacker_dir) && defined?(::Sprockets) ? sprockets_file : webpacker_file
84
+ end
85
+
86
+ protected
87
+
88
+ def normalize_and_verify
89
+ normalize
90
+ verify
91
+ end
92
+
93
+ def pathname(*parts)
94
+ Pathname.new(File.join(*parts))
95
+ end
96
+
97
+ def default_file_name
98
+ dts? ? "routes.d.ts" : "routes.js"
99
+ end
100
+
101
+ def normalize
102
+ self.module_type = module_type&.upcase || 'NIL'
103
+ end
104
+
105
+ def verify
106
+ if module_type != 'NIL' && namespace
107
+ raise "JsRoutes namespace option can only be used if module_type is nil"
108
+ end
109
+ end
110
+ end
111
+ end
@@ -1,4 +1,4 @@
1
- class JsRoutes
1
+ module JsRoutes
2
2
  class SprocketsExtension
3
3
  def initialize(filename, &block)
4
4
  @filename = filename
@@ -0,0 +1,154 @@
1
+ require "js_routes/configuration"
2
+ require "js_routes/route"
3
+
4
+ module JsRoutes
5
+ class Instance
6
+
7
+ attr_reader :configuration
8
+ #
9
+ # Implementation
10
+ #
11
+
12
+ def initialize(options = {})
13
+ @configuration = JsRoutes.configuration.merge(options)
14
+ end
15
+
16
+ def generate
17
+ # Ensure routes are loaded. If they're not, load them.
18
+ if named_routes.empty? && application.respond_to?(:reload_routes!)
19
+ application.reload_routes!
20
+ end
21
+ content = File.read(@configuration.source_file)
22
+
23
+ if !@configuration.dts?
24
+ content = js_variables.inject(content) do |js, (key, value)|
25
+ js.gsub!("RubyVariables.#{key}", value.to_s) ||
26
+ raise("Missing key #{key} in JS template")
27
+ end
28
+ end
29
+ content + routes_export + prevent_types_export
30
+ end
31
+
32
+ def generate!
33
+ # Some libraries like Devise did not load their routes yet
34
+ # so we will wait until initialization process finishes
35
+ # https://github.com/railsware/js-routes/issues/7
36
+ Rails.configuration.after_initialize do
37
+ file_path = Rails.root.join(@configuration.output_file)
38
+ source_code = generate
39
+
40
+ # We don't need to rewrite file if it already exist and have same content.
41
+ # It helps asset pipeline or webpack understand that file wasn't changed.
42
+ next if File.exist?(file_path) && File.read(file_path) == source_code
43
+
44
+ File.open(file_path, 'w') do |f|
45
+ f.write source_code
46
+ end
47
+ end
48
+ end
49
+
50
+ protected
51
+
52
+ def js_variables
53
+ {
54
+ 'GEM_VERSION' => JsRoutes::VERSION,
55
+ 'ROUTES_OBJECT' => routes_object,
56
+ 'RAILS_VERSION' => ActionPack.version,
57
+ 'DEPRECATED_GLOBBING_BEHAVIOR' => ActionPack::VERSION::MAJOR == 4 && ActionPack::VERSION::MINOR == 0,
58
+
59
+ 'APP_CLASS' => application.class.to_s,
60
+ 'NAMESPACE' => json(@configuration.namespace),
61
+ 'DEFAULT_URL_OPTIONS' => json(@configuration.default_url_options),
62
+ 'PREFIX' => json(@configuration.prefix),
63
+ 'SPECIAL_OPTIONS_KEY' => json(@configuration.special_options_key),
64
+ 'SERIALIZER' => @configuration.serializer || json(nil),
65
+ 'MODULE_TYPE' => json(@configuration.module_type),
66
+ 'WRAPPER' => @configuration.esm? ? 'const __jsr = ' : '',
67
+ }
68
+ end
69
+
70
+ def application
71
+ @configuration.application
72
+ end
73
+
74
+ def json(string)
75
+ JsRoutes.json(string)
76
+ end
77
+
78
+ def named_routes
79
+ application.routes.named_routes.to_a
80
+ end
81
+
82
+ def routes_object
83
+ return json({}) if @configuration.modern?
84
+ properties = routes_list.map do |comment, name, body|
85
+ "#{comment}#{name}: #{body}".indent(2)
86
+ end
87
+ "{\n" + properties.join(",\n\n") + "}\n"
88
+ end
89
+
90
+ def static_exports
91
+ [:configure, :config, :serialize].map do |name|
92
+ [
93
+ "", name,
94
+ @configuration.dts? ?
95
+ "RouterExposedMethods['#{name}']" :
96
+ "__jsr.#{name}"
97
+ ]
98
+ end
99
+ end
100
+
101
+ def routes_export
102
+ return "" unless @configuration.modern?
103
+ [*static_exports, *routes_list].map do |comment, name, body|
104
+ "#{comment}export const #{name}#{export_separator}#{body};\n\n"
105
+ end.join
106
+ end
107
+
108
+ def prevent_types_export
109
+ return "" unless @configuration.dts?
110
+ <<-JS
111
+ // By some reason this line prevents all types in a file
112
+ // from being automatically exported
113
+ export {};
114
+ JS
115
+ end
116
+
117
+ def export_separator
118
+ @configuration.dts? ? ': ' : ' = '
119
+ end
120
+
121
+ def routes_list
122
+ named_routes.sort_by(&:first).flat_map do |_, route|
123
+ route_helpers_if_match(route) + mounted_app_routes(route)
124
+ end
125
+ end
126
+
127
+ def mounted_app_routes(route)
128
+ rails_engine_app = app_from_route(route)
129
+ if rails_engine_app.respond_to?(:superclass) &&
130
+ rails_engine_app.superclass == Rails::Engine && !route.path.anchored
131
+ rails_engine_app.routes.named_routes.flat_map do |_, engine_route|
132
+ route_helpers_if_match(engine_route, route)
133
+ end
134
+ else
135
+ []
136
+ end
137
+ end
138
+
139
+ def app_from_route(route)
140
+ app = route.app
141
+ # rails engine in Rails 4.2 use additional
142
+ # ActionDispatch::Routing::Mapper::Constraints, which contain app
143
+ if app.respond_to?(:app) && app.respond_to?(:constraints)
144
+ app.app
145
+ else
146
+ app
147
+ end
148
+ end
149
+
150
+ def route_helpers_if_match(route, parent_route = nil)
151
+ Route.new(@configuration, route, parent_route).helpers
152
+ end
153
+ end
154
+ end
@@ -1,4 +1,4 @@
1
- class JsRoutes
1
+ module JsRoutes
2
2
  # A Rack middleware that automatically updates routes file
3
3
  # whenever routes.rb is modified
4
4
  #
@@ -1,4 +1,4 @@
1
- class JsRoutes
1
+ module JsRoutes
2
2
  class Route #:nodoc:
3
3
  FILTERED_DEFAULT_PARTS = [:controller, :action]
4
4
  URL_OPTIONS = [:protocol, :domain, :host, :port, :subdomain]
@@ -1,3 +1,3 @@
1
- class JsRoutes
2
- VERSION = "2.2.1"
1
+ module JsRoutes
2
+ VERSION = "2.2.2"
3
3
  end
data/lib/js_routes.rb CHANGED
@@ -1,116 +1,12 @@
1
- require 'uri'
2
- require "pathname"
3
-
4
1
  if defined?(::Rails) && defined?(::Sprockets::Railtie)
5
2
  require 'js_routes/engine'
6
3
  end
7
4
  require 'js_routes/version'
8
- require "js_routes/route"
5
+ require "js_routes/configuration"
6
+ require "js_routes/instance"
9
7
  require 'active_support/core_ext/string/indent'
10
8
 
11
- class JsRoutes
12
-
13
- class Configuration
14
- DEFAULTS = {
15
- namespace: nil,
16
- exclude: [],
17
- include: //,
18
- file: nil,
19
- prefix: -> { Rails.application.config.relative_url_root || "" },
20
- url_links: false,
21
- camel_case: false,
22
- default_url_options: {},
23
- compact: false,
24
- serializer: nil,
25
- special_options_key: "_options",
26
- application: -> { Rails.application },
27
- module_type: 'ESM',
28
- documentation: true,
29
- } #:nodoc:
30
-
31
- attr_accessor(*DEFAULTS.keys)
32
-
33
- def initialize(attributes = nil)
34
- assign(DEFAULTS)
35
- return unless attributes
36
- assign(attributes)
37
- end
38
-
39
- def assign(attributes)
40
- attributes.each do |attribute, value|
41
- value = value.call if value.is_a?(Proc)
42
- send(:"#{attribute}=", value)
43
- end
44
- normalize_and_verify
45
- self
46
- end
47
-
48
- def [](attribute)
49
- send(attribute)
50
- end
51
-
52
- def merge(attributes)
53
- clone.assign(attributes)
54
- end
55
-
56
- def to_hash
57
- Hash[*members.zip(values).flatten(1)].symbolize_keys
58
- end
59
-
60
- def esm?
61
- module_type === 'ESM'
62
- end
63
-
64
- def dts?
65
- self.module_type === 'DTS'
66
- end
67
-
68
- def modern?
69
- esm? || dts?
70
- end
71
-
72
- def require_esm
73
- raise "ESM module type is required" unless modern?
74
- end
75
-
76
- def source_file
77
- File.dirname(__FILE__) + "/" + default_file_name
78
- end
79
-
80
- def output_file
81
- webpacker_dir = pathname('app', 'javascript')
82
- sprockets_dir = pathname('app','assets','javascripts')
83
- file_name = file || default_file_name
84
- sprockets_file = sprockets_dir.join(file_name)
85
- webpacker_file = webpacker_dir.join(file_name)
86
- !Dir.exist?(webpacker_dir) && defined?(::Sprockets) ? sprockets_file : webpacker_file
87
- end
88
-
89
- def normalize_and_verify
90
- normalize
91
- verify
92
- end
93
-
94
- protected
95
-
96
- def pathname(*parts)
97
- Pathname.new(File.join(*parts))
98
- end
99
-
100
- def default_file_name
101
- dts? ? "routes.d.ts" : "routes.js"
102
- end
103
-
104
- def normalize
105
- self.module_type = module_type&.upcase || 'NIL'
106
- end
107
-
108
- def verify
109
- if module_type != 'NIL' && namespace
110
- raise "JsRoutes namespace option can only be used if module_type is nil"
111
- end
112
- end
113
- end
9
+ module JsRoutes
114
10
 
115
11
  #
116
12
  # API
@@ -118,8 +14,7 @@ class JsRoutes
118
14
 
119
15
  class << self
120
16
  def setup(&block)
121
- configuration.tap(&block) if block
122
- configuration.normalize_and_verify
17
+ configuration.assign(&block)
123
18
  end
124
19
 
125
20
  def configuration
@@ -127,11 +22,11 @@ class JsRoutes
127
22
  end
128
23
 
129
24
  def generate(**opts)
130
- new(opts).generate
25
+ Instance.new(opts).generate
131
26
  end
132
27
 
133
- def generate!(file_name=nil, **opts)
134
- new(file: file_name, **opts).generate!
28
+ def generate!(file_name = configuration.file, **opts)
29
+ Instance.new(file: file_name, **opts).generate!
135
30
  end
136
31
 
137
32
  def definitions(**opts)
@@ -147,154 +42,6 @@ class JsRoutes
147
42
  ActiveSupport::JSON.encode(string)
148
43
  end
149
44
  end
150
-
151
- attr_reader :configuration
152
- #
153
- # Implementation
154
- #
155
-
156
- def initialize(options = {})
157
- @configuration = self.class.configuration.merge(options)
158
- end
159
-
160
- def generate
161
- # Ensure routes are loaded. If they're not, load them.
162
- if named_routes.empty? && application.respond_to?(:reload_routes!)
163
- application.reload_routes!
164
- end
165
- content = File.read(@configuration.source_file)
166
-
167
- if !@configuration.dts?
168
- content = js_variables.inject(content) do |js, (key, value)|
169
- js.gsub!("RubyVariables.#{key}", value.to_s) ||
170
- raise("Missing key #{key} in JS template")
171
- end
172
- end
173
- content + routes_export + prevent_types_export
174
- end
175
-
176
- def generate!
177
- # Some libraries like Devise did not load their routes yet
178
- # so we will wait until initialization process finishes
179
- # https://github.com/railsware/js-routes/issues/7
180
- Rails.configuration.after_initialize do
181
- file_path = Rails.root.join(@configuration.output_file)
182
- source_code = generate
183
-
184
- # We don't need to rewrite file if it already exist and have same content.
185
- # It helps asset pipeline or webpack understand that file wasn't changed.
186
- next if File.exist?(file_path) && File.read(file_path) == source_code
187
-
188
- File.open(file_path, 'w') do |f|
189
- f.write source_code
190
- end
191
- end
192
- end
193
-
194
- protected
195
-
196
- def js_variables
197
- {
198
- 'GEM_VERSION' => JsRoutes::VERSION,
199
- 'ROUTES_OBJECT' => routes_object,
200
- 'RAILS_VERSION' => ActionPack.version,
201
- 'DEPRECATED_GLOBBING_BEHAVIOR' => ActionPack::VERSION::MAJOR == 4 && ActionPack::VERSION::MINOR == 0,
202
-
203
- 'APP_CLASS' => application.class.to_s,
204
- 'NAMESPACE' => json(@configuration.namespace),
205
- 'DEFAULT_URL_OPTIONS' => json(@configuration.default_url_options),
206
- 'PREFIX' => json(@configuration.prefix),
207
- 'SPECIAL_OPTIONS_KEY' => json(@configuration.special_options_key),
208
- 'SERIALIZER' => @configuration.serializer || json(nil),
209
- 'MODULE_TYPE' => json(@configuration.module_type),
210
- 'WRAPPER' => @configuration.esm? ? 'const __jsr = ' : '',
211
- }
212
- end
213
-
214
- def application
215
- @configuration.application
216
- end
217
-
218
- def json(string)
219
- self.class.json(string)
220
- end
221
-
222
- def named_routes
223
- application.routes.named_routes.to_a
224
- end
225
-
226
- def routes_object
227
- return json({}) if @configuration.modern?
228
- properties = routes_list.map do |comment, name, body|
229
- "#{comment}#{name}: #{body}".indent(2)
230
- end
231
- "{\n" + properties.join(",\n\n") + "}\n"
232
- end
233
-
234
- def static_exports
235
- [:configure, :config, :serialize].map do |name|
236
- [
237
- "", name,
238
- @configuration.dts? ?
239
- "RouterExposedMethods['#{name}']" :
240
- "__jsr.#{name}"
241
- ]
242
- end
243
- end
244
-
245
- def routes_export
246
- return "" unless @configuration.modern?
247
- [*static_exports, *routes_list].map do |comment, name, body|
248
- "#{comment}export const #{name}#{export_separator}#{body};\n\n"
249
- end.join
250
- end
251
-
252
- def prevent_types_export
253
- return "" unless @configuration.dts?
254
- <<-JS
255
- // By some reason this line prevents all types in a file
256
- // from being automatically exported
257
- export {};
258
- JS
259
- end
260
-
261
- def export_separator
262
- @configuration.dts? ? ': ' : ' = '
263
- end
264
-
265
- def routes_list
266
- named_routes.sort_by(&:first).flat_map do |_, route|
267
- route_helpers_if_match(route) + mounted_app_routes(route)
268
- end
269
- end
270
-
271
- def mounted_app_routes(route)
272
- rails_engine_app = app_from_route(route)
273
- if rails_engine_app.respond_to?(:superclass) &&
274
- rails_engine_app.superclass == Rails::Engine && !route.path.anchored
275
- rails_engine_app.routes.named_routes.flat_map do |_, engine_route|
276
- route_helpers_if_match(engine_route, route)
277
- end
278
- else
279
- []
280
- end
281
- end
282
-
283
- def app_from_route(route)
284
- app = route.app
285
- # rails engine in Rails 4.2 use additional
286
- # ActionDispatch::Routing::Mapper::Constraints, which contain app
287
- if app.respond_to?(:app) && app.respond_to?(:constraints)
288
- app.app
289
- else
290
- app
291
- end
292
- end
293
-
294
- def route_helpers_if_match(route, parent_route = nil)
295
- Route.new(@configuration, route, parent_route).helpers
296
- end
297
-
298
45
  module Generators
299
46
  end
300
47
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: js-routes
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bogdan Gusiev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-20 00:00:00.000000000 Z
11
+ date: 2022-02-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -170,9 +170,11 @@ files:
170
170
  - js-routes.gemspec
171
171
  - lib/js-routes.rb
172
172
  - lib/js_routes.rb
173
+ - lib/js_routes/configuration.rb
173
174
  - lib/js_routes/engine.rb
174
175
  - lib/js_routes/generators/middleware.rb
175
176
  - lib/js_routes/generators/webpacker.rb
177
+ - lib/js_routes/instance.rb
176
178
  - lib/js_routes/middleware.rb
177
179
  - lib/js_routes/route.rb
178
180
  - lib/js_routes/version.rb