js_from_routes 2.0.0 → 2.0.1

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: 120fa96855c034323a664b851019f5d1df7bd418de5578af5fa074b80451ca3e
4
- data.tar.gz: 7a39747149294d21f74568296c4cab44f2e93ea172c85bad0d721e686c16ce74
3
+ metadata.gz: 5663dc5fb9fd9062e81af864e59d7fb8ec61625d5db06c0f55c04307afde8314
4
+ data.tar.gz: 5dc7aa69994d396c22472c249e216045a4b6466b4041d7df6974f9bf6f6e5f75
5
5
  SHA512:
6
- metadata.gz: 77d1b1b6bef1a59d68bc1452dcb8ade3de38123ae907687bab9017347897a440b6f8b57ce6874f46d8873c6fcddf0e0480e38aa46a02fd91c39600c5c9980eca
7
- data.tar.gz: 993bf91cfd887d1c645313b305f2f5d1c095ed31f3232d34b7dcbf575eefafdbadaeb3fb6948e00f1b1614e8f38e86217dd6c5bb2c55c508df771584441bde53
6
+ metadata.gz: 782f8ee6ca92ab3bcb84220e4012bb235b8aeafeeff88e54499f93d35fa75fbfcde6799460a53f4dd6dd2990ac9a3934dd07632a7e1e4b7ecea527f66a324e1c
7
+ data.tar.gz: ebdc1552cfae84ce61f36ad7f70fc302c6b1994b29ad06956391ab9701cd8a639dbb4d8317d2122907b474b114f01dd36e61de22d7b3aa118f694349d64a2a12
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [2.0.1](https://github.com/ElMassimo/js_from_routes/compare/js_from_routes@2.0.0...js_from_routes@2.0.1) (2021-03-14)
2
+
3
+
4
+
1
5
  # [2.0.0](https://github.com/ElMassimo/js_from_routes/compare/v1.0.3...js_from_routes@2.0.0) (2021-03-13)
2
6
 
3
7
  ### Features ⚡️
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2021 Máximo Mussini
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -8,12 +8,34 @@ require "pathname"
8
8
  # Public: Automatically generates JS for Rails routes with { export: true }.
9
9
  # Generates one file per controller, and one function per route.
10
10
  module JsFromRoutes
11
+ # Internal: Helper class used as a presenter for the all helpers template.
12
+ class AllRoutes
13
+ attr_reader :helpers
14
+
15
+ def initialize(helpers, config)
16
+ @helpers, @config = helpers, config
17
+ end
18
+
19
+ # Public: Used to check whether the file should be generated again, changes
20
+ # based on the configuration, and route definition.
21
+ def cache_key
22
+ helpers.map(&:import_filename).join + File.read(@config.template_all_path)
23
+ end
24
+
25
+ # Internal: Name of the JS file where all helpers will be exported.
26
+ def filename
27
+ path = @config.all_helpers_file
28
+ path = "index#{File.extname(@config.file_suffix)}" if path == true
29
+ @config.output_folder.join(path)
30
+ end
31
+ end
32
+
11
33
  # Internal: Helper class used as a presenter for the routes template.
12
- class Routes
34
+ class ControllerRoutes
13
35
  attr_reader :routes
14
36
 
15
- def initialize(routes, config)
16
- @config = config
37
+ def initialize(controller, routes, config)
38
+ @controller, @config = controller, config
17
39
  @routes = routes
18
40
  .uniq { |route| route.requirements.fetch(:action) }
19
41
  .map { |route| Route.new(route, config.helper_mappings) }
@@ -22,7 +44,7 @@ module JsFromRoutes
22
44
  # Public: Used to check whether the file should be generated again, changes
23
45
  # based on the configuration, and route definition.
24
46
  def cache_key
25
- Digest::MD5.hexdigest(routes.map(&:inspect).join + [File.read(@config.template_path), @config.helper_mappings.inspect].join)
47
+ routes.map(&:inspect).join + [File.read(@config.template_path), @config.helper_mappings.inspect].join
26
48
  end
27
49
 
28
50
  # Public: Exposes the preferred import library to the generator.
@@ -30,10 +52,24 @@ module JsFromRoutes
30
52
  @config.client_library
31
53
  end
32
54
 
33
- # Internal: By performing the evaluation here, we ensure only "routes" is
34
- # exposed to the ERB template as a local variable.
35
- def evaluate(compiled_template)
36
- instance_eval(compiled_template)
55
+ # Internal: Name of the JS file with helpers for the the given controller.
56
+ def filename
57
+ @config.output_folder.join(basename)
58
+ end
59
+
60
+ # Public: Name of the JS file with helpers for the the given controller.
61
+ def import_filename
62
+ @config.output_folder.basename.join((basename.split(".")[0]).to_s)
63
+ end
64
+
65
+ # Public: Name of the file as a valid JS variable.
66
+ def js_name
67
+ @controller.camelize(:lower).tr(":", "_")
68
+ end
69
+
70
+ # Internal: The base name of the JS file to be written.
71
+ def basename
72
+ "#{@controller.camelize}#{@config.file_suffix}".tr_s(":", "/")
37
73
  end
38
74
  end
39
75
 
@@ -70,6 +106,43 @@ module JsFromRoutes
70
106
  end
71
107
  end
72
108
 
109
+ # Internal: Represents a compiled template that can write itself to a file.
110
+ class Template
111
+ def initialize(template_path)
112
+ # NOTE: The compiled ERB template, used to generate JS code.
113
+ @compiled_template = Erubi::Engine.new(File.read(template_path), filename: template_path).src
114
+ end
115
+
116
+ # Public: Checks if the cache is fresh, or renders the template with the
117
+ # specified variables, and writes the updated result to a file.
118
+ def write_if_changed(object)
119
+ write_file_if_changed(object.filename, object.cache_key) { render_template(object) }
120
+ end
121
+
122
+ private
123
+
124
+ # Internal: Returns a String with the generated JS code.
125
+ def render_template(object)
126
+ object.instance_eval(@compiled_template)
127
+ end
128
+
129
+ # Internal: Writes if the file does not exist or the cache key has changed.
130
+ # The cache strategy consists of a comment on the first line of the file.
131
+ #
132
+ # Yields to receive the rendered file content when it needs to.
133
+ def write_file_if_changed(name, cache_key)
134
+ FileUtils.mkdir_p(name.dirname)
135
+ cache_key_comment = "// JsFromRoutes CacheKey #{Digest::MD5.hexdigest(cache_key)}\n"
136
+ File.open(name, "a+") { |file|
137
+ if file.gets != cache_key_comment
138
+ file.truncate(0)
139
+ file.write(cache_key_comment)
140
+ file.write(yield)
141
+ end
142
+ }
143
+ end
144
+ end
145
+
73
146
  class << self
74
147
  # Public: Configuration of the code generator.
75
148
  def config
@@ -82,23 +155,36 @@ module JsFromRoutes
82
155
  def generate!(app_or_routes = Rails.application)
83
156
  raise ArgumentError, "A Rails app must be defined, or you must specify a custom `output_folder`" if config.output_folder.blank?
84
157
  rails_routes = app_or_routes.is_a?(::Rails::Engine) ? app_or_routes.routes.routes : app_or_routes
85
- @compiled_template = nil # Clear on every code reload in case the template changed.
86
- exported_routes_by_controller(rails_routes).each do |controller, controller_routes|
87
- routes = Routes.new(controller_routes, config)
88
- write_if_changed(filename_for(controller), routes.cache_key) { render_template(routes) }
89
- end
158
+ generate_files exported_routes_by_controller(rails_routes)
90
159
  end
91
160
 
92
161
  private
93
162
 
163
+ def generate_files(exported_routes)
164
+ template = Template.new(config.template_path)
165
+ generate_file_for_all exported_routes.map { |controller, routes|
166
+ ControllerRoutes.new(controller, routes, config).tap do |routes|
167
+ template.write_if_changed routes
168
+ end
169
+ }
170
+ end
171
+
172
+ def generate_file_for_all(routes)
173
+ return unless config.all_helpers_file && !routes.empty?
174
+
175
+ Template.new(config.template_all_path).write_if_changed AllRoutes.new(routes, config)
176
+ end
177
+
94
178
  def default_config(root)
95
179
  dir = %w[frontend packs javascript assets].find { |dir| root.join("app", dir).exist? }
96
180
  {
181
+ all_helpers_file: true,
97
182
  client_library: "@js-from-routes/client",
98
183
  file_suffix: "Api.js",
99
184
  helper_mappings: {"index" => "list", "show" => "get"},
100
185
  output_folder: root.join("app", dir, "api"),
101
186
  template_path: File.expand_path("template.js.erb", __dir__),
187
+ template_all_path: File.expand_path("template_all.js.erb", __dir__),
102
188
  }
103
189
  end
104
190
 
@@ -110,39 +196,5 @@ module JsFromRoutes
110
196
  route.requirements.fetch(:controller)
111
197
  }
112
198
  end
113
-
114
- # Internal: Name of the JS file with helpers for the the given controller.
115
- def filename_for(controller)
116
- config.output_folder.join("#{controller.camelize}#{config.file_suffix}".tr_s(":", "/"))
117
- end
118
-
119
- # Internal: Returns a String with the JS generated for a controller's routes.
120
- def render_template(routes)
121
- routes.evaluate(compiled_template)
122
- end
123
-
124
- # Internal: Returns the compiled ERB to generate JS from a set of routes.
125
- def compiled_template
126
- @compiled_template ||= begin
127
- template = File.read(config.template_path)
128
- Erubi::Engine.new(template, filename: config.template_path).src
129
- end
130
- end
131
-
132
- # Internal: Writes if the file does not exist or the cache key has changed.
133
- # The cache strategy consists of a comment on the first line of the file.
134
- #
135
- # Yields to receive the rendered file content when it needs to.
136
- def write_if_changed(name, cache_key)
137
- FileUtils.mkdir_p(name.dirname)
138
- cache_key_comment = "// JsFromRoutes CacheKey #{cache_key}\n"
139
- File.open(name, "a+") { |file|
140
- if file.gets != cache_key_comment
141
- file.truncate(0)
142
- file.write(cache_key_comment)
143
- file.write(yield)
144
- end
145
- }
146
- end
147
199
  end
148
200
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "rails/railtie"
4
+
3
5
  # NOTE: Not strictly required, but it helps to simplify the setup.
4
6
  class JsFromRoutes::Railtie < Rails::Railtie
5
7
  railtie_name :js_from_routes
@@ -3,7 +3,7 @@
3
3
  import { definePathHelper } from '<%= client_library %>'
4
4
 
5
5
  export default {
6
- <% routes.each_with_index do |route, index| %>
6
+ <% routes.each do |route| %>
7
7
  <%= route.helper %>: definePathHelper('<%= route.verb %>', '<%= route.path %>'),
8
8
  <% end %>
9
9
  }
@@ -0,0 +1,11 @@
1
+ //
2
+ // DO NOT MODIFY: This file was automatically generated by JsFromRoutes.
3
+ <% helpers.each do |helper| %>
4
+ import <%= helper.js_name %> from '~/<%= helper.import_filename %>'
5
+ <% end %>
6
+
7
+ export default {
8
+ <% helpers.each do |helper| %>
9
+ <%= helper.js_name %>,
10
+ <% end %>
11
+ }
@@ -4,5 +4,5 @@
4
4
  # Generates one file per controller, and one function per route.
5
5
  module JsFromRoutes
6
6
  # Public: This library adheres to semantic versioning.
7
- VERSION = "2.0.0"
7
+ VERSION = "2.0.1"
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: js_from_routes
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Máximo Mussini
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-13 00:00:00.000000000 Z
11
+ date: 2021-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -139,11 +139,13 @@ extra_rdoc_files:
139
139
  - README.md
140
140
  files:
141
141
  - CHANGELOG.md
142
+ - LICENSE.txt
142
143
  - README.md
143
144
  - lib/js_from_routes.rb
144
145
  - lib/js_from_routes/generator.rb
145
146
  - lib/js_from_routes/railtie.rb
146
147
  - lib/js_from_routes/template.js.erb
148
+ - lib/js_from_routes/template_all.js.erb
147
149
  - lib/js_from_routes/version.rb
148
150
  homepage: https://github.com/ElMassimo/js_from_routes
149
151
  licenses: