js-routes 2.0.8 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4f78bfaf0cba479c48245d0606cc10b262481e854f3fc82e7195a8b58548bf7a
4
- data.tar.gz: 118cafad50e73568ba4b1758821af072194e9570178f1f9caf067785e9f5a0f5
3
+ metadata.gz: 242f329ab92abe8be4a2fa3790f72a3f161a6c2355b2392eae484a36a91d3a24
4
+ data.tar.gz: 120e5191eccfe3a8978c89ecb690a4f93a62279b249c58bc84b9273fe3e900c7
5
5
  SHA512:
6
- metadata.gz: 95490b886a00861b0fe4a5e2419c67ec804bbb94a916edefe333acd2e0c94b407137952b97e4bf70d928ad1ebc5cf47333b5b5083f0dc227a43be2d3ebba7648
7
- data.tar.gz: 666d2862d8a86e760176afdfdd62711a34202a4725d08609e5f5bf69732becb8829826ddeccaca0f8cacffa6a78022e69a05872ea26ce550e7352a9bfde0d0e4
6
+ metadata.gz: e1998fd3c98dff227905bfcd8a09be8bb6901d3da7293b60d1a6f11c3a2627c623372324a13010cbe425eb7b93781fa64db042c08e7b4123d4a50ec8bd8814b2
7
+ data.tar.gz: 5395c808f148bd39a99de0ce748cbb3a57c27620f048764bfcf6a455ac6ce2bbc43e282f4c660ba019f8d4b5df39a316728bb673d56b2667aecb667dde82d91b
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## master
2
2
 
3
+ ## v2.1.0
4
+
5
+ * Support typescript defintions file aka `routes.d.ts`. See [Readme.md](./Readme.md#definitions) for more information.
6
+
3
7
  ## v2.0.8
4
8
 
5
9
  * Forbid usage of `namespace` option if `module_type` is not `nil`. [#281](https://github.com/railsware/js-routes/issues/281).
data/Readme.md CHANGED
@@ -20,22 +20,26 @@ gem "js-routes"
20
20
 
21
21
  Run:
22
22
 
23
- ```
23
+ ``` sh
24
24
  rake js:routes
25
+ # OR for typescript support
26
+ rake js:routes:typescript
25
27
  ```
26
28
 
27
- Make routes available globally in `app/javascript/packs/application.js`:
29
+
30
+ Individual routes can be imported using:
28
31
 
29
32
  ``` javascript
30
- import * as Routes from 'routes';
31
- window.Routes = Routes;
33
+ import {edit_post_path, posts_path} from 'routes';
34
+ console.log(posts_path({format: 'json'})) // => "/posts.json"
35
+ console.log(edit_post_path(1)) // => "/posts/1/edit"
32
36
  ```
33
37
 
34
- Individual routes can be imported using:
38
+ Make routes available globally in `app/javascript/packs/application.js`:
35
39
 
36
40
  ``` javascript
37
- import {edit_post_path} from 'routes';
38
- console.log(edit_post_path(1))
41
+ import * as Routes from 'routes';
42
+ window.Routes = Routes;
39
43
  ```
40
44
 
41
45
  **Note**: that this setup requires `rake js:routes` to be run each time routes file is updated.
@@ -91,6 +95,22 @@ import * as Routes from 'routes.js.erb';
91
95
  window.Routes = Routes;
92
96
  ```
93
97
 
98
+ <div id='definitions'></div>
99
+
100
+ #### Typescript Definitions
101
+
102
+ JsRoutes has typescript support out of the box. In order to generate typscript definitions file (aka `routes.d.ts`) you can call:
103
+
104
+ ``` ruby
105
+ JsRoutes.definitions!
106
+ ```
107
+
108
+ Or create an automatic updates file at `app/javascript/routes.d.ts.erb`:
109
+
110
+ ``` erb
111
+ <%= JsRoutes.defintions %>
112
+ ```
113
+
94
114
  #### Sprockets (Deprecated)
95
115
 
96
116
  If you are using [Sprockets](https://github.com/rails/sprockets-rails) you may configure js-routes in the following way.
@@ -147,7 +167,7 @@ Routes.config(); // current config
147
167
  Options to configure JavaScript file generator. These options are only available in Ruby context but not JavaScript.
148
168
 
149
169
  * `module_type` - JavaScript module type for generated code. [Article](https://dev.to/iggredible/what-the-heck-are-cjs-amd-umd-and-esm-ikm)
150
- * Options: `ESM`, `UMD`, `CJS`, `AMD`, `nil`.
170
+ * Options: `ESM`, `UMD`, `CJS`, `AMD`, `DTS`, `nil`.
151
171
  * Default: `ESM`
152
172
  * `nil` option can be used in case you don't want generated code to export anything.
153
173
  * `documentation` - specifies if each route should be annotated with [JSDoc](https://jsdoc.app/) comment
@@ -324,9 +344,9 @@ Split your routes into multiple files related to each section of your website li
324
344
 
325
345
  ``` javascript
326
346
  // admin-routes.js.erb
327
- <%= JsRoutes.generate(include: /^admin_/)
347
+ <%= JsRoutes.generate(include: /^admin_/) %>
328
348
  // app-routes.js.erb
329
- <%= JsRoutes.generate(exclude: /^admin_/)
349
+ <%= JsRoutes.generate(exclude: /^admin_/) %>
330
350
  ```
331
351
 
332
352
  ## Advantages over alternatives
data/js-routes.gemspec CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |s|
25
25
 
26
26
  s.add_runtime_dependency(%q<railties>, [">= 4"])
27
27
  s.add_development_dependency(%q<sprockets-rails>)
28
- s.add_development_dependency(%q<rspec>, [">= 3.0.0"])
28
+ s.add_development_dependency(%q<rspec>, [">= 3.10.0"])
29
29
  s.add_development_dependency(%q<bundler>, [">= 1.1.0"])
30
30
  s.add_development_dependency(%q<appraisal>, [">= 0.5.2"])
31
31
  s.add_development_dependency(%q<bump>, [">= 0.10.0"])
@@ -1,3 +1,3 @@
1
1
  class JsRoutes
2
- VERSION = "2.0.8"
2
+ VERSION = "2.1.0"
3
3
  end
data/lib/js_routes.rb CHANGED
@@ -7,48 +7,26 @@ require 'active_support/core_ext/string/indent'
7
7
 
8
8
  class JsRoutes
9
9
 
10
- #
11
- # OPTIONS
12
- #
10
+ class Configuration
11
+ DEFAULTS = {
12
+ namespace: nil,
13
+ exclude: [],
14
+ include: //,
15
+ file: nil,
16
+ prefix: -> { Rails.application.config.relative_url_root || "" },
17
+ url_links: false,
18
+ camel_case: false,
19
+ default_url_options: {},
20
+ compact: false,
21
+ serializer: nil,
22
+ special_options_key: "_options",
23
+ application: -> { Rails.application },
24
+ module_type: 'ESM',
25
+ documentation: true,
26
+ } #:nodoc:
27
+
28
+ attr_accessor(*DEFAULTS.keys)
13
29
 
14
- DEFAULTS = {
15
- namespace: nil,
16
- exclude: [],
17
- include: //,
18
- file: -> do
19
- webpacker_dir = Rails.root.join('app', 'javascript')
20
- sprockets_dir = Rails.root.join('app','assets','javascripts')
21
- sprockets_file = sprockets_dir.join('routes.js')
22
- webpacker_file = webpacker_dir.join('routes.js')
23
- !Dir.exist?(webpacker_dir) && defined?(::Sprockets) ? sprockets_file : webpacker_file
24
- end,
25
- prefix: -> { Rails.application.config.relative_url_root || "" },
26
- url_links: false,
27
- camel_case: false,
28
- default_url_options: {},
29
- compact: false,
30
- serializer: nil,
31
- special_options_key: "_options",
32
- application: -> { Rails.application },
33
- module_type: 'ESM',
34
- documentation: true,
35
- } #:nodoc:
36
-
37
- NODE_TYPES = {
38
- GROUP: 1,
39
- CAT: 2,
40
- SYMBOL: 3,
41
- OR: 4,
42
- STAR: 5,
43
- LITERAL: 6,
44
- SLASH: 7,
45
- DOT: 8
46
- } #:nodoc:
47
-
48
- FILTERED_DEFAULT_PARTS = [:controller, :action] #:nodoc:
49
- URL_OPTIONS = [:protocol, :domain, :host, :port, :subdomain] #:nodoc:
50
-
51
- class Configuration < Struct.new(*DEFAULTS.keys)
52
30
  def initialize(attributes = nil)
53
31
  assign(DEFAULTS)
54
32
  return unless attributes
@@ -80,6 +58,27 @@ class JsRoutes
80
58
  module_type === 'ESM'
81
59
  end
82
60
 
61
+ def dts?
62
+ self.module_type === 'DTS'
63
+ end
64
+
65
+ def modern?
66
+ esm? || dts?
67
+ end
68
+
69
+ def source_file
70
+ File.dirname(__FILE__) + "/" + default_file_name
71
+ end
72
+
73
+ def output_file
74
+ webpacker_dir = Rails.root.join('app', 'javascript')
75
+ sprockets_dir = Rails.root.join('app','assets','javascripts')
76
+ file_name = file || default_file_name
77
+ sprockets_file = sprockets_dir.join(file_name)
78
+ webpacker_file = webpacker_dir.join(file_name)
79
+ !Dir.exist?(webpacker_dir) && defined?(::Sprockets) ? sprockets_file : webpacker_file
80
+ end
81
+
83
82
  def normalize_and_verify
84
83
  normalize
85
84
  verify
@@ -87,6 +86,10 @@ class JsRoutes
87
86
 
88
87
  protected
89
88
 
89
+ def default_file_name
90
+ dts? ? "routes.d.ts" : "routes.js"
91
+ end
92
+
90
93
  def normalize
91
94
  self.module_type = module_type&.upcase || 'NIL'
92
95
  end
@@ -116,12 +119,13 @@ class JsRoutes
116
119
  new(opts).generate
117
120
  end
118
121
 
119
- def generate!(file_name=nil, opts = {})
120
- if file_name.is_a?(Hash)
121
- opts = file_name
122
- file_name = opts[:file]
123
- end
124
- new(opts).generate!(file_name)
122
+ def generate!(file_name=nil, **opts)
123
+ new(file: file_name, **opts).generate!
124
+ end
125
+
126
+ def definitions!(file_name = nil, **opts)
127
+ file_name ||= configuration.file&.sub!(%r{\.(j|t)s\Z}, ".d.ts")
128
+ new(file: file_name, module_type: 'DTS', **opts).generate!
125
129
  end
126
130
 
127
131
  def json(string)
@@ -142,48 +146,55 @@ class JsRoutes
142
146
  if named_routes.to_a.empty? && application.respond_to?(:reload_routes!)
143
147
  application.reload_routes!
144
148
  end
149
+ content = File.read(@configuration.source_file)
145
150
 
146
- {
147
- 'GEM_VERSION' => JsRoutes::VERSION,
148
- 'ROUTES_OBJECT' => routes_object,
149
- 'RAILS_VERSION' => ActionPack.version,
150
- 'DEPRECATED_GLOBBING_BEHAVIOR' => ActionPack::VERSION::MAJOR == 4 && ActionPack::VERSION::MINOR == 0,
151
-
152
- 'APP_CLASS' => application.class.to_s,
153
- 'NAMESPACE' => json(@configuration.namespace),
154
- 'DEFAULT_URL_OPTIONS' => json(@configuration.default_url_options),
155
- 'PREFIX' => json(@configuration.prefix),
156
- 'SPECIAL_OPTIONS_KEY' => json(@configuration.special_options_key),
157
- 'SERIALIZER' => @configuration.serializer || json(nil),
158
- 'MODULE_TYPE' => json(@configuration.module_type),
159
- 'WRAPPER' => @configuration.esm? ? 'const __jsr = ' : '',
160
- }.inject(File.read(File.dirname(__FILE__) + "/routes.js")) do |js, (key, value)|
161
- js.gsub!("RubyVariables.#{key}", value.to_s) ||
151
+ if !@configuration.dts?
152
+ content = js_variables.inject(content) do |js, (key, value)|
153
+ js.gsub!("RubyVariables.#{key}", value.to_s) ||
162
154
  raise("Missing key #{key} in JS template")
163
- end + routes_export
155
+ end
156
+ end
157
+ content + routes_export + prevent_types_export
164
158
  end
165
159
 
166
- def generate!(file_name = nil)
167
- # Some libraries like Devise do not yet loaded their routes so we will wait
168
- # until initialization process finish
160
+ def generate!
161
+ # Some libraries like Devise did not load their routes yet
162
+ # so we will wait until initialization process finishes
169
163
  # https://github.com/railsware/js-routes/issues/7
170
164
  Rails.configuration.after_initialize do
171
- file_name ||= self.class.configuration['file']
172
- file_path = Rails.root.join(file_name)
173
- js_content = generate
165
+ file_path = Rails.root.join(@configuration.output_file)
166
+ source_code = generate
174
167
 
175
168
  # We don't need to rewrite file if it already exist and have same content.
176
169
  # It helps asset pipeline or webpack understand that file wasn't changed.
177
- next if File.exist?(file_path) && File.read(file_path) == js_content
170
+ next if File.exist?(file_path) && File.read(file_path) == source_code
178
171
 
179
172
  File.open(file_path, 'w') do |f|
180
- f.write js_content
173
+ f.write source_code
181
174
  end
182
175
  end
183
176
  end
184
177
 
185
178
  protected
186
179
 
180
+ def js_variables
181
+ {
182
+ 'GEM_VERSION' => JsRoutes::VERSION,
183
+ 'ROUTES_OBJECT' => routes_object,
184
+ 'RAILS_VERSION' => ActionPack.version,
185
+ 'DEPRECATED_GLOBBING_BEHAVIOR' => ActionPack::VERSION::MAJOR == 4 && ActionPack::VERSION::MINOR == 0,
186
+
187
+ 'APP_CLASS' => application.class.to_s,
188
+ 'NAMESPACE' => json(@configuration.namespace),
189
+ 'DEFAULT_URL_OPTIONS' => json(@configuration.default_url_options),
190
+ 'PREFIX' => json(@configuration.prefix),
191
+ 'SPECIAL_OPTIONS_KEY' => json(@configuration.special_options_key),
192
+ 'SERIALIZER' => @configuration.serializer || json(nil),
193
+ 'MODULE_TYPE' => json(@configuration.module_type),
194
+ 'WRAPPER' => @configuration.esm? ? 'const __jsr = ' : '',
195
+ }
196
+ end
197
+
187
198
  def application
188
199
  @configuration.application
189
200
  end
@@ -197,32 +208,52 @@ class JsRoutes
197
208
  end
198
209
 
199
210
  def routes_object
200
- return json({}) if @configuration.esm?
211
+ return json({}) if @configuration.modern?
201
212
  properties = routes_list.map do |comment, name, body|
202
213
  "#{comment}#{name}: #{body}".indent(2)
203
214
  end
204
215
  "{\n" + properties.join(",\n\n") + "}\n"
205
216
  end
206
217
 
207
- STATIC_EXPORTS = [:configure, :config, :serialize].map do |name|
208
- ["", name, "__jsr.#{name}"]
218
+ def static_exports
219
+ [:configure, :config, :serialize].map do |name|
220
+ [
221
+ "", name,
222
+ @configuration.dts? ?
223
+ "RouterExposedMethods['#{name}']" :
224
+ "__jsr.#{name}"
225
+ ]
226
+ end
209
227
  end
210
228
 
211
229
  def routes_export
212
- return "" unless @configuration.esm?
213
- [*STATIC_EXPORTS, *routes_list].map do |comment, name, body|
214
- "#{comment}export const #{name} = #{body};"
215
- end.join("\n\n")
230
+ return "" unless @configuration.modern?
231
+ [*static_exports, *routes_list].map do |comment, name, body|
232
+ "#{comment}export const #{name}#{export_separator}#{body};\n\n"
233
+ end.join
234
+ end
235
+
236
+ def prevent_types_export
237
+ return "" unless @configuration.dts?
238
+ <<-JS
239
+ // By some reason this line prevents all types in a file
240
+ // from being automatically exported
241
+ export {};
242
+ JS
243
+ end
244
+
245
+ def export_separator
246
+ @configuration.dts? ? ': ' : ' = '
216
247
  end
217
248
 
218
249
  def routes_list
219
250
  named_routes.sort_by(&:first).flat_map do |_, route|
220
251
  route_helpers_if_match(route) + mounted_app_routes(route)
221
- end.compact
252
+ end
222
253
  end
223
254
 
224
255
  def mounted_app_routes(route)
225
- rails_engine_app = get_app_from_route(route)
256
+ rails_engine_app = app_from_route(route)
226
257
  if rails_engine_app.respond_to?(:superclass) &&
227
258
  rails_engine_app.superclass == Rails::Engine && !route.path.anchored
228
259
  rails_engine_app.routes.named_routes.flat_map do |_, engine_route|
@@ -233,7 +264,7 @@ class JsRoutes
233
264
  end
234
265
  end
235
266
 
236
- def get_app_from_route(route)
267
+ def app_from_route(route)
237
268
  # rails engine in Rails 4.2 use additional
238
269
  # ActionDispatch::Routing::Mapper::Constraints, which contain app
239
270
  if route.app.respond_to?(:app) && route.app.respond_to?(:constraints)
@@ -248,6 +279,19 @@ class JsRoutes
248
279
  end
249
280
 
250
281
  class JsRoute #:nodoc:
282
+ FILTERED_DEFAULT_PARTS = [:controller, :action]
283
+ URL_OPTIONS = [:protocol, :domain, :host, :port, :subdomain]
284
+ NODE_TYPES = {
285
+ GROUP: 1,
286
+ CAT: 2,
287
+ SYMBOL: 3,
288
+ OR: 4,
289
+ STAR: 5,
290
+ LITERAL: 6,
291
+ SLASH: 7,
292
+ DOT: 8
293
+ }
294
+
251
295
  attr_reader :configuration, :route, :parent_route
252
296
 
253
297
  def initialize(configuration, route, parent_route = nil)
@@ -257,24 +301,36 @@ class JsRoutes
257
301
  end
258
302
 
259
303
  def helpers
260
- unless match_configuration?
261
- []
262
- else
263
- [false, true].map do |absolute|
264
- absolute && !@configuration[:url_links] ?
265
- nil : [ documentation, helper_name(absolute), body(absolute) ]
266
- end
304
+ helper_types.map do |absolute|
305
+ [ documentation, helper_name(absolute), body(absolute) ]
267
306
  end
268
307
  end
269
308
 
270
- protected
309
+ def helper_types
310
+ return [] unless match_configuration?
311
+ @configuration[:url_links] ? [true, false] : [false]
312
+ end
271
313
 
272
314
  def body(absolute)
273
- "__jsr.r(#{arguments(absolute).map{|a| json(a)}.join(', ')})"
315
+ @configuration.dts? ?
316
+ definition_body : "__jsr.r(#{arguments(absolute).map{|a| json(a)}.join(', ')})"
274
317
  end
275
318
 
319
+ def definition_body
320
+ args = required_parts.map{|p| "#{apply_case(p)}: RequiredRouteParameter"}
321
+ args << "options?: #{optional_parts_type} & RouteOptions"
322
+ "((\n#{args.join(",\n").indent(2)}\n) => string) & RouteHelperExtras"
323
+ end
324
+
325
+ def optional_parts_type
326
+ @optional_parts_type ||=
327
+ "{" + optional_parts.map {|p| "#{p}?: OptionalRouteParameter"}.join(', ') + "}"
328
+ end
329
+
330
+ protected
331
+
276
332
  def arguments(absolute)
277
- absolute ? base_arguments + [true] : base_arguments
333
+ absolute ? [*base_arguments, true] : base_arguments
278
334
  end
279
335
 
280
336
  def match_configuration?
@@ -319,6 +375,10 @@ JS
319
375
  route.required_parts
320
376
  end
321
377
 
378
+ def optional_parts
379
+ route.path.optional_names
380
+ end
381
+
322
382
  def base_arguments
323
383
  @base_arguments ||= [parts_table, serialize(spec, parent_spec)]
324
384
  end
data/lib/routes.d.ts CHANGED
@@ -2,14 +2,38 @@
2
2
  * File generated by js-routes RubyVariables.GEM_VERSION
3
3
  * Based on Rails RubyVariables.RAILS_VERSION routes of RubyVariables.APP_CLASS
4
4
  */
5
- declare type RouteParameter = unknown;
6
- declare type RouteParameters = Record<string, RouteParameter>;
7
- declare type Serializer = (value: unknown) => string;
8
- declare type RouteHelper = {
9
- (...args: RouteParameter[]): string;
5
+ declare type Optional<T> = {
6
+ [P in keyof T]?: T[P] | null;
7
+ };
8
+ declare type BaseRouteParameter = string | boolean | Date | number;
9
+ declare type MethodRouteParameter = BaseRouteParameter | (() => BaseRouteParameter);
10
+ declare type ModelRouteParameter = {
11
+ id: MethodRouteParameter;
12
+ } | {
13
+ to_param: MethodRouteParameter;
14
+ } | {
15
+ toParam: MethodRouteParameter;
16
+ };
17
+ declare type RequiredRouteParameter = BaseRouteParameter | ModelRouteParameter;
18
+ declare type OptionalRouteParameter = undefined | null | RequiredRouteParameter;
19
+ declare type QueryRouteParameter = OptionalRouteParameter | QueryRouteParameter[] | {
20
+ [k: string]: QueryRouteParameter;
21
+ };
22
+ declare type RouteParameters = Record<string, QueryRouteParameter>;
23
+ declare type Serializable = Record<string, unknown>;
24
+ declare type Serializer = (value: Serializable) => string;
25
+ declare type RouteHelperExtras = {
10
26
  requiredParams(): string[];
11
27
  toString(): string;
12
28
  };
29
+ declare type RequiredParameters<T extends number> = T extends 1 ? [RequiredRouteParameter] : T extends 2 ? [RequiredRouteParameter, RequiredRouteParameter] : T extends 3 ? [RequiredRouteParameter, RequiredRouteParameter, RequiredRouteParameter] : T extends 4 ? [
30
+ RequiredRouteParameter,
31
+ RequiredRouteParameter,
32
+ RequiredRouteParameter,
33
+ RequiredRouteParameter
34
+ ] : RequiredRouteParameter[];
35
+ declare type RouteHelperOptions<T extends string> = RouteOptions & Optional<Record<T, OptionalRouteParameter>>;
36
+ declare type RouteHelper<T extends number = number, U extends string = string> = ((...args: [...RequiredParameters<T>, RouteHelperOptions<U>]) => string) & RouteHelperExtras;
13
37
  declare type RouteHelpers = Record<string, RouteHelper>;
14
38
  declare type Configuration = {
15
39
  prefix: string;
@@ -17,9 +41,6 @@ declare type Configuration = {
17
41
  special_options_key: string;
18
42
  serializer: Serializer;
19
43
  };
20
- declare type Optional<T> = {
21
- [P in keyof T]?: T[P] | null;
22
- };
23
44
  interface RouterExposedMethods {
24
45
  config(): Configuration;
25
46
  configure(arg: Partial<Configuration>): Configuration;
@@ -29,15 +50,16 @@ declare type KeywordUrlOptions = Optional<{
29
50
  host: string;
30
51
  protocol: string;
31
52
  subdomain: string;
32
- port: string;
53
+ port: string | number;
33
54
  anchor: string;
34
55
  trailing_slash: boolean;
35
56
  }>;
57
+ declare type RouteOptions = KeywordUrlOptions & RouteParameters;
36
58
  declare type PartsTable = Record<string, {
37
59
  r?: boolean;
38
- d?: unknown;
60
+ d?: OptionalRouteParameter;
39
61
  }>;
40
- declare type ModuleType = "CJS" | "AMD" | "UMD" | "ESM" | "NIL";
62
+ declare type ModuleType = "CJS" | "AMD" | "UMD" | "ESM" | "DTS" | "NIL";
41
63
  declare const RubyVariables: {
42
64
  PREFIX: string;
43
65
  DEPRECATED_GLOBBING_BEHAVIOR: boolean;
data/lib/routes.js CHANGED
@@ -76,6 +76,15 @@ RubyVariables.WRAPPER((that) => {
76
76
  return !!Root;
77
77
  },
78
78
  },
79
+ DTS: {
80
+ // Acts the same as ESM
81
+ define(routes) {
82
+ ModuleReferences.ESM.define(routes);
83
+ },
84
+ isSupported() {
85
+ return ModuleReferences.ESM.isSupported();
86
+ },
87
+ },
79
88
  };
80
89
  class ParametersMissing extends Error {
81
90
  constructor(...keys) {
@@ -162,7 +171,7 @@ RubyVariables.WRAPPER((that) => {
162
171
  }
163
172
  looks_like_serialized_model(object) {
164
173
  return (this.is_object(object) &&
165
- !object[this.configuration.special_options_key] &&
174
+ !(this.configuration.special_options_key in object) &&
166
175
  ("id" in object || "to_param" in object || "toParam" in object));
167
176
  }
168
177
  path_identifier(object) {
@@ -320,9 +329,7 @@ RubyVariables.WRAPPER((that) => {
320
329
  }
321
330
  }
322
331
  encode_segment(segment) {
323
- return segment.replace(UriEncoderSegmentRegex, function (str) {
324
- return encodeURIComponent(str);
325
- });
332
+ return segment.replace(UriEncoderSegmentRegex, (str) => encodeURIComponent(str));
326
333
  }
327
334
  is_optional_node(node) {
328
335
  return [NodeTypes.STAR, NodeTypes.SYMBOL, NodeTypes.CAT].includes(node);
@@ -410,32 +417,17 @@ RubyVariables.WRAPPER((that) => {
410
417
  port = port ? ":" + port : "";
411
418
  return protocol + "://" + subdomain + hostname + port;
412
419
  }
413
- has_location() {
414
- return this.is_not_nullable(window) && !!window.location;
415
- }
416
420
  current_host() {
417
- if (this.has_location()) {
418
- return window.location.hostname;
419
- }
420
- else {
421
- return null;
422
- }
421
+ var _a;
422
+ return ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.hostname) || "";
423
423
  }
424
424
  current_protocol() {
425
- if (this.has_location() && window.location.protocol !== "") {
426
- return window.location.protocol.replace(/:$/, "");
427
- }
428
- else {
429
- return "http";
430
- }
425
+ var _a, _b;
426
+ return ((_b = (_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.protocol) === null || _b === void 0 ? void 0 : _b.replace(/:$/, "")) || "http";
431
427
  }
432
428
  current_port() {
433
- if (this.has_location() && window.location.port !== "") {
434
- return window.location.port;
435
- }
436
- else {
437
- return "";
438
- }
429
+ var _a;
430
+ return ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.port) || "";
439
431
  }
440
432
  is_object(value) {
441
433
  return (typeof value === "object" &&
data/lib/routes.ts CHANGED
@@ -3,15 +3,51 @@
3
3
  * Based on Rails RubyVariables.RAILS_VERSION routes of RubyVariables.APP_CLASS
4
4
  */
5
5
 
6
- type RouteParameter = unknown;
7
- type RouteParameters = Record<string, RouteParameter>;
8
- type Serializer = (value: unknown) => string;
9
- type RouteHelper = {
10
- (...args: RouteParameter[]): string;
6
+ type Optional<T> = { [P in keyof T]?: T[P] | null };
7
+ type BaseRouteParameter = string | boolean | Date | number;
8
+ type MethodRouteParameter = BaseRouteParameter | (() => BaseRouteParameter);
9
+ type ModelRouteParameter =
10
+ | { id: MethodRouteParameter }
11
+ | { to_param: MethodRouteParameter }
12
+ | { toParam: MethodRouteParameter };
13
+ type RequiredRouteParameter = BaseRouteParameter | ModelRouteParameter;
14
+ type OptionalRouteParameter = undefined | null | RequiredRouteParameter;
15
+ type QueryRouteParameter =
16
+ | OptionalRouteParameter
17
+ | QueryRouteParameter[]
18
+ | { [k: string]: QueryRouteParameter };
19
+ type RouteParameters = Record<string, QueryRouteParameter>;
20
+
21
+ type Serializable = Record<string, unknown>;
22
+ type Serializer = (value: Serializable) => string;
23
+ type RouteHelperExtras = {
11
24
  requiredParams(): string[];
12
25
  toString(): string;
13
26
  };
14
27
 
28
+ type RequiredParameters<T extends number> = T extends 1
29
+ ? [RequiredRouteParameter]
30
+ : T extends 2
31
+ ? [RequiredRouteParameter, RequiredRouteParameter]
32
+ : T extends 3
33
+ ? [RequiredRouteParameter, RequiredRouteParameter, RequiredRouteParameter]
34
+ : T extends 4
35
+ ? [
36
+ RequiredRouteParameter,
37
+ RequiredRouteParameter,
38
+ RequiredRouteParameter,
39
+ RequiredRouteParameter
40
+ ]
41
+ : RequiredRouteParameter[];
42
+
43
+ type RouteHelperOptions<T extends string> = RouteOptions &
44
+ Optional<Record<T, OptionalRouteParameter>>;
45
+
46
+ type RouteHelper<T extends number = number, U extends string = string> = ((
47
+ ...args: [...RequiredParameters<T>, RouteHelperOptions<U>]
48
+ ) => string) &
49
+ RouteHelperExtras;
50
+
15
51
  type RouteHelpers = Record<string, RouteHelper>;
16
52
 
17
53
  type Configuration = {
@@ -21,7 +57,6 @@ type Configuration = {
21
57
  serializer: Serializer;
22
58
  };
23
59
 
24
- type Optional<T> = { [P in keyof T]?: T[P] | null };
25
60
  interface RouterExposedMethods {
26
61
  config(): Configuration;
27
62
  configure(arg: Partial<Configuration>): Configuration;
@@ -32,14 +67,16 @@ type KeywordUrlOptions = Optional<{
32
67
  host: string;
33
68
  protocol: string;
34
69
  subdomain: string;
35
- port: string;
70
+ port: string | number;
36
71
  anchor: string;
37
72
  trailing_slash: boolean;
38
73
  }>;
39
74
 
40
- type PartsTable = Record<string, { r?: boolean; d?: unknown }>;
75
+ type RouteOptions = KeywordUrlOptions & RouteParameters;
41
76
 
42
- type ModuleType = "CJS" | "AMD" | "UMD" | "ESM" | "NIL";
77
+ type PartsTable = Record<string, { r?: boolean; d?: OptionalRouteParameter }>;
78
+
79
+ type ModuleType = "CJS" | "AMD" | "UMD" | "ESM" | "DTS" | "NIL";
43
80
 
44
81
  declare const RubyVariables: {
45
82
  PREFIX: string;
@@ -93,7 +130,7 @@ RubyVariables.WRAPPER(
93
130
 
94
131
  const Root = that;
95
132
  type ModuleDefinition = {
96
- define: (routes: unknown) => void;
133
+ define: (routes: RouterExposedMethods) => void;
97
134
  isSupported: () => boolean;
98
135
  };
99
136
  const ModuleReferences: Record<ModuleType, ModuleDefinition> = {
@@ -155,6 +192,15 @@ RubyVariables.WRAPPER(
155
192
  return !!Root;
156
193
  },
157
194
  },
195
+ DTS: {
196
+ // Acts the same as ESM
197
+ define(routes) {
198
+ ModuleReferences.ESM.define(routes);
199
+ },
200
+ isSupported() {
201
+ return ModuleReferences.ESM.isSupported();
202
+ },
203
+ },
158
204
  };
159
205
 
160
206
  class ParametersMissing extends Error {
@@ -225,16 +271,16 @@ RubyVariables.WRAPPER(
225
271
  return result.join("&");
226
272
  }
227
273
 
228
- serialize(object: unknown): string {
274
+ serialize(object: Serializable): string {
229
275
  return this.configuration.serializer(object);
230
276
  }
231
277
 
232
278
  extract_options(
233
279
  number_of_params: number,
234
- args: RouteParameter[]
280
+ args: OptionalRouteParameter[]
235
281
  ): {
236
- args: RouteParameter[];
237
- options: KeywordUrlOptions & RouteParameters;
282
+ args: OptionalRouteParameter[];
283
+ options: RouteOptions;
238
284
  } {
239
285
  const last_el = args[args.length - 1];
240
286
  if (
@@ -247,32 +293,27 @@ RubyVariables.WRAPPER(
247
293
  }
248
294
  return {
249
295
  args: args.slice(0, args.length - 1),
250
- options: last_el as KeywordUrlOptions & RouteParameters,
296
+ options: (last_el as any) as RouteOptions,
251
297
  };
252
298
  } else {
253
299
  return { args, options: {} };
254
300
  }
255
301
  }
256
302
 
257
- looks_like_serialized_model(
258
- object: any
259
- ): object is
260
- | { id: unknown }
261
- | { to_param: unknown }
262
- | { toParam: unknown } {
303
+ looks_like_serialized_model(object: any): object is ModelRouteParameter {
263
304
  return (
264
305
  this.is_object(object) &&
265
- !object[this.configuration.special_options_key] &&
306
+ !(this.configuration.special_options_key in object) &&
266
307
  ("id" in object || "to_param" in object || "toParam" in object)
267
308
  );
268
309
  }
269
310
 
270
- path_identifier(object: unknown): string {
311
+ path_identifier(object: QueryRouteParameter): string {
271
312
  const result = this.unwrap_path_identifier(object);
272
313
  return this.is_nullable(result) || result === false ? "" : "" + result;
273
314
  }
274
315
 
275
- unwrap_path_identifier(object: any): unknown {
316
+ unwrap_path_identifier(object: QueryRouteParameter): unknown {
276
317
  let result: any = object;
277
318
  if (!this.is_object(object)) {
278
319
  return object;
@@ -293,7 +334,7 @@ RubyVariables.WRAPPER(
293
334
  parts: string[],
294
335
  required_params: string[],
295
336
  default_options: RouteParameters,
296
- call_arguments: RouteParameter[]
337
+ call_arguments: OptionalRouteParameter[]
297
338
  ): {
298
339
  keyword_parameters: KeywordUrlOptions;
299
340
  query_parameters: RouteParameters;
@@ -357,7 +398,7 @@ RubyVariables.WRAPPER(
357
398
  default_options: RouteParameters,
358
399
  route: RouteTree,
359
400
  absolute: boolean,
360
- args: RouteParameter[]
401
+ args: OptionalRouteParameter[]
361
402
  ): string {
362
403
  const {
363
404
  keyword_parameters,
@@ -467,9 +508,9 @@ RubyVariables.WRAPPER(
467
508
  }
468
509
 
469
510
  encode_segment(segment: string): string {
470
- return segment.replace(UriEncoderSegmentRegex, function (str) {
471
- return encodeURIComponent(str);
472
- });
511
+ return segment.replace(UriEncoderSegmentRegex, (str) =>
512
+ encodeURIComponent(str)
513
+ );
473
514
  }
474
515
 
475
516
  is_optional_node(node: NodeTypes): boolean {
@@ -550,7 +591,7 @@ RubyVariables.WRAPPER(
550
591
  default_options[part] = value;
551
592
  }
552
593
  }
553
- const result = (...args: RouteParameter[]): string => {
594
+ const result = (...args: OptionalRouteParameter[]): string => {
554
595
  return this.build_route(
555
596
  parts,
556
597
  required_params,
@@ -564,7 +605,7 @@ RubyVariables.WRAPPER(
564
605
  result.toString = () => {
565
606
  return this.build_path_spec(route_spec);
566
607
  };
567
- return result;
608
+ return result as any;
568
609
  }
569
610
 
570
611
  route_url(route_defaults: KeywordUrlOptions): string {
@@ -583,31 +624,16 @@ RubyVariables.WRAPPER(
583
624
  return protocol + "://" + subdomain + hostname + port;
584
625
  }
585
626
 
586
- has_location(): boolean {
587
- return this.is_not_nullable(window) && !!window.location;
588
- }
589
-
590
- current_host(): string | null {
591
- if (this.has_location()) {
592
- return window.location.hostname;
593
- } else {
594
- return null;
595
- }
627
+ current_host(): string {
628
+ return window?.location?.hostname || "";
596
629
  }
597
630
 
598
631
  current_protocol(): string {
599
- if (this.has_location() && window.location.protocol !== "") {
600
- return window.location.protocol.replace(/:$/, "");
601
- } else {
602
- return "http";
603
- }
632
+ return window?.location?.protocol?.replace(/:$/, "") || "http";
604
633
  }
634
+
605
635
  current_port(): string {
606
- if (this.has_location() && window.location.port !== "") {
607
- return window.location.port;
608
- } else {
609
- return "";
610
- }
636
+ return window?.location?.port || "";
611
637
  }
612
638
 
613
639
  is_object(value: unknown): value is Record<string, unknown> {
@@ -694,7 +720,7 @@ RubyVariables.WRAPPER(
694
720
  config: (): Configuration => {
695
721
  return Utils.config();
696
722
  },
697
- serialize: (object: unknown): string => {
723
+ serialize: (object: Serializable): string => {
698
724
  return Utils.serialize(object);
699
725
  },
700
726
  ...RubyVariables.ROUTES_OBJECT,
@@ -1,8 +1,14 @@
1
1
  namespace :js do
2
- desc "Make a js file that will have functions that will return restful routes/urls."
2
+ desc "Make a js file with all rails route URL helpers"
3
3
  task routes: :environment do
4
4
  require "js-routes"
5
-
6
5
  JsRoutes.generate!
7
6
  end
7
+
8
+ namespace :routes do
9
+ desc "Make a js file with all rails route URL helpers and typescript definitions for them"
10
+ task typescript: "js:routes" do
11
+ JsRoutes.definitions!
12
+ end
13
+ end
8
14
  end
@@ -0,0 +1,114 @@
1
+ /**
2
+ * File generated by js-routes RubyVariables.GEM_VERSION
3
+ * Based on Rails RubyVariables.RAILS_VERSION routes of RubyVariables.APP_CLASS
4
+ */
5
+ declare type Optional<T> = {
6
+ [P in keyof T]?: T[P] | null;
7
+ };
8
+ declare type BaseRouteParameter = string | boolean | Date | number;
9
+ declare type MethodRouteParameter = BaseRouteParameter | (() => BaseRouteParameter);
10
+ declare type ModelRouteParameter = {
11
+ id: MethodRouteParameter;
12
+ } | {
13
+ to_param: MethodRouteParameter;
14
+ } | {
15
+ toParam: MethodRouteParameter;
16
+ };
17
+ declare type RequiredRouteParameter = BaseRouteParameter | ModelRouteParameter;
18
+ declare type OptionalRouteParameter = undefined | null | RequiredRouteParameter;
19
+ declare type QueryRouteParameter = OptionalRouteParameter | QueryRouteParameter[] | {
20
+ [k: string]: QueryRouteParameter;
21
+ };
22
+ declare type RouteParameters = Record<string, QueryRouteParameter>;
23
+ declare type Serializable = Record<string, unknown>;
24
+ declare type Serializer = (value: Serializable) => string;
25
+ declare type RouteHelperExtras = {
26
+ requiredParams(): string[];
27
+ toString(): string;
28
+ };
29
+ declare type RequiredParameters<T extends number> = T extends 1 ? [RequiredRouteParameter] : T extends 2 ? [RequiredRouteParameter, RequiredRouteParameter] : T extends 3 ? [RequiredRouteParameter, RequiredRouteParameter, RequiredRouteParameter] : T extends 4 ? [
30
+ RequiredRouteParameter,
31
+ RequiredRouteParameter,
32
+ RequiredRouteParameter,
33
+ RequiredRouteParameter
34
+ ] : RequiredRouteParameter[];
35
+ declare type RouteHelperOptions<T extends string> = RouteOptions & Optional<Record<T, OptionalRouteParameter>>;
36
+ declare type RouteHelper<T extends number = number, U extends string = string> = ((...args: [...RequiredParameters<T>, RouteHelperOptions<U>]) => string) & RouteHelperExtras;
37
+ declare type RouteHelpers = Record<string, RouteHelper>;
38
+ declare type Configuration = {
39
+ prefix: string;
40
+ default_url_options: RouteParameters;
41
+ special_options_key: string;
42
+ serializer: Serializer;
43
+ };
44
+ interface RouterExposedMethods {
45
+ config(): Configuration;
46
+ configure(arg: Partial<Configuration>): Configuration;
47
+ serialize: Serializer;
48
+ }
49
+ declare type KeywordUrlOptions = Optional<{
50
+ host: string;
51
+ protocol: string;
52
+ subdomain: string;
53
+ port: string | number;
54
+ anchor: string;
55
+ trailing_slash: boolean;
56
+ }>;
57
+ declare type RouteOptions = KeywordUrlOptions & RouteParameters;
58
+ declare type PartsTable = Record<string, {
59
+ r?: boolean;
60
+ d?: OptionalRouteParameter;
61
+ }>;
62
+ declare type ModuleType = "CJS" | "AMD" | "UMD" | "ESM" | "DTS" | "NIL";
63
+ declare const RubyVariables: {
64
+ PREFIX: string;
65
+ DEPRECATED_GLOBBING_BEHAVIOR: boolean;
66
+ SPECIAL_OPTIONS_KEY: string;
67
+ DEFAULT_URL_OPTIONS: RouteParameters;
68
+ SERIALIZER: Serializer;
69
+ NAMESPACE: string;
70
+ ROUTES_OBJECT: RouteHelpers;
71
+ MODULE_TYPE: ModuleType;
72
+ WRAPPER: <T>(callback: T) => T;
73
+ };
74
+ declare const define: undefined | (((arg: unknown[], callback: () => unknown) => void) & {
75
+ amd?: unknown;
76
+ });
77
+ declare const module: {
78
+ exports: any;
79
+ } | undefined;
80
+ export const configure: RouterExposedMethods['configure'];
81
+
82
+ export const config: RouterExposedMethods['config'];
83
+
84
+ export const serialize: RouterExposedMethods['serialize'];
85
+
86
+ /**
87
+ * Generates rails route to
88
+ * /inboxes/:inbox_id/messages/:message_id/attachments/:id(.:format)
89
+ * @param {any} inbox_id
90
+ * @param {any} message_id
91
+ * @param {any} id
92
+ * @param {object | undefined} options
93
+ * @returns {string} route path
94
+ */
95
+ export const inbox_message_attachment_path: ((
96
+ inbox_id: RequiredRouteParameter,
97
+ message_id: RequiredRouteParameter,
98
+ id: RequiredRouteParameter,
99
+ options?: {format?: OptionalRouteParameter} & RouteOptions
100
+ ) => string) & RouteHelperExtras;
101
+
102
+ /**
103
+ * Generates rails route to
104
+ * /inboxes(.:format)
105
+ * @param {object | undefined} options
106
+ * @returns {string} route path
107
+ */
108
+ export const inboxes_path: ((
109
+ options?: {format?: OptionalRouteParameter} & RouteOptions
110
+ ) => string) & RouteHelperExtras;
111
+
112
+ // By some reason this line prevents all types in a file
113
+ // from being automatically exported
114
+ export {};
@@ -0,0 +1,56 @@
1
+ import {
2
+ inbox_message_attachment_path,
3
+ inboxes_path,
4
+ serialize,
5
+ configure,
6
+ config,
7
+ } from "./routes.spec";
8
+
9
+ // Route Helpers
10
+ inboxes_path();
11
+ inboxes_path({
12
+ locale: "en",
13
+ search: {
14
+ q: "ukraine",
15
+ page: 3,
16
+ keywords: ["large", "small", { advanced: true }],
17
+ },
18
+ });
19
+
20
+ inbox_message_attachment_path(1, "2", true);
21
+ inbox_message_attachment_path(
22
+ { id: 1 },
23
+ { to_param: () => "2" },
24
+ { toParam: () => true }
25
+ );
26
+ inbox_message_attachment_path(1, "2", true, { format: "json" });
27
+ inboxes_path.toString();
28
+ inboxes_path.requiredParams();
29
+
30
+ // serialize test
31
+ const SerializerArgument = {
32
+ locale: "en",
33
+ search: {
34
+ q: "ukraine",
35
+ page: 3,
36
+ keywords: ["large", "small", { advanced: true }],
37
+ },
38
+ };
39
+ serialize(SerializerArgument);
40
+ config().serializer(SerializerArgument);
41
+
42
+ // configure test
43
+ configure({
44
+ default_url_options: { port: 1, host: null },
45
+ prefix: "",
46
+ special_options_key: "_options",
47
+ serializer: (value) => JSON.stringify(value),
48
+ });
49
+
50
+ // config tests
51
+ const Config = config();
52
+ console.log(
53
+ Config.prefix,
54
+ Config.default_url_options,
55
+ Config.special_options_key
56
+ );
@@ -0,0 +1,111 @@
1
+
2
+ require "active_support/core_ext/string/strip"
3
+ require "fileutils"
4
+ require "open3"
5
+ require "spec_helper"
6
+
7
+ describe JsRoutes, "compatibility with DTS" do
8
+
9
+ OPTIONS = {module_type: 'DTS', include: [/^inboxes$/, /^inbox_message_attachment$/]}
10
+ let(:extra_options) do
11
+ {}
12
+ end
13
+
14
+ let(:generated_js) do
15
+ JsRoutes.generate({**OPTIONS, **extra_options})
16
+ end
17
+
18
+ context "when file is generated" do
19
+ let(:dir_name) do
20
+ File.expand_path(__dir__ + "/dts")
21
+ end
22
+
23
+ let(:file_name) do
24
+ dir_name + "/routes.spec.d.ts"
25
+ end
26
+
27
+ before do
28
+ FileUtils.mkdir_p(dir_name)
29
+ File.write(file_name, generated_js)
30
+ end
31
+
32
+ it "has no compile errors", :slow do
33
+ command = "yarn tsc --strict --noEmit -p spec/tsconfig.json"
34
+ stdout, stderr, status = Open3.capture3(command)
35
+ expect(stderr).to eq("")
36
+ expect(stdout).to include("Done in ")
37
+ expect(status).to eq(0)
38
+ end
39
+ end
40
+
41
+ context "when camel case is enabled" do
42
+ let(:extra_options) { {camel_case: true} }
43
+
44
+ it "camelizes route name and arguments" do
45
+
46
+ expect(generated_js).to include(<<-DOC.rstrip)
47
+ /**
48
+ * Generates rails route to
49
+ * /inboxes/:inbox_id/messages/:message_id/attachments/:id(.:format)
50
+ * @param {any} inboxId
51
+ * @param {any} messageId
52
+ * @param {any} id
53
+ * @param {object | undefined} options
54
+ * @returns {string} route path
55
+ */
56
+ export const inboxMessageAttachmentPath: ((
57
+ inboxId: RequiredRouteParameter,
58
+ messageId: RequiredRouteParameter,
59
+ id: RequiredRouteParameter,
60
+ options?: {format?: OptionalRouteParameter} & RouteOptions
61
+ ) => string) & RouteHelperExtras;
62
+ DOC
63
+ end
64
+ end
65
+
66
+ it "exports route helpers" do
67
+ expect(generated_js).to include(<<-DOC.rstrip)
68
+ /**
69
+ * Generates rails route to
70
+ * /inboxes(.:format)
71
+ * @param {object | undefined} options
72
+ * @returns {string} route path
73
+ */
74
+ export const inboxes_path: ((
75
+ options?: {format?: OptionalRouteParameter} & RouteOptions
76
+ ) => string) & RouteHelperExtras;
77
+ DOC
78
+ expect(generated_js).to include(<<-DOC.rstrip)
79
+ /**
80
+ * Generates rails route to
81
+ * /inboxes/:inbox_id/messages/:message_id/attachments/:id(.:format)
82
+ * @param {any} inbox_id
83
+ * @param {any} message_id
84
+ * @param {any} id
85
+ * @param {object | undefined} options
86
+ * @returns {string} route path
87
+ */
88
+ export const inbox_message_attachment_path: ((
89
+ inbox_id: RequiredRouteParameter,
90
+ message_id: RequiredRouteParameter,
91
+ id: RequiredRouteParameter,
92
+ options?: {format?: OptionalRouteParameter} & RouteOptions
93
+ ) => string) & RouteHelperExtras
94
+ DOC
95
+ end
96
+
97
+ it "exports utility methods" do
98
+ expect(generated_js).to include("export const serialize: RouterExposedMethods['serialize'];")
99
+ end
100
+
101
+ it "prevents all types from automatic export" do
102
+ expect(generated_js).to include("export {};")
103
+ end
104
+
105
+ describe "compiled javascript asset" do
106
+ subject { ERB.new(File.read("app/assets/javascripts/js-routes.js.erb")).result(binding) }
107
+ it "should have js routes code" do
108
+ is_expected.to include("export const inbox_message_path = __jsr.r(")
109
+ end
110
+ end
111
+ end
@@ -5,7 +5,7 @@
5
5
  require 'spec_helper'
6
6
  require "fileutils"
7
7
 
8
- describe "after Rails initialization" do
8
+ describe "after Rails initialization", :slow do
9
9
  NAME = Rails.root.join('app', 'assets', 'javascripts', 'routes.js').to_s
10
10
 
11
11
  def sprockets_v3?
@@ -122,7 +122,7 @@ describe "after Rails initialization" do
122
122
  end
123
123
  end
124
124
 
125
- describe "JSRoutes thread safety" do
125
+ describe "JSRoutes thread safety", :slow do
126
126
  before do
127
127
  begin
128
128
  Rails.application.initialize!
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "../tsconfig.json",
3
+ "include": ["./**/*.spec.ts"]
4
+ }
data/tsconfig.json CHANGED
@@ -3,14 +3,10 @@
3
3
  "target": "es2019",
4
4
  "lib": ["es2020", "dom"],
5
5
  "module": "commonjs",
6
- "outDir": "lib",
7
6
  "sourceMap": false,
8
7
  "declaration": true,
9
8
  "allowSyntheticDefaultImports": true,
10
- "resolveJsonModule": true,
11
- "typeRoots": ["node_modules/@types", "./@types"],
12
-
13
- "strict": true,
9
+ "resolveJsonModule": false,
14
10
  "strictNullChecks": true,
15
11
  "noImplicitAny": true,
16
12
  "noImplicitThis": true,
@@ -22,11 +18,11 @@
22
18
  "forceConsistentCasingInFileNames": true,
23
19
  "emitDecoratorMetadata": true,
24
20
  "experimentalDecorators": true
21
+
25
22
  },
26
23
  "ts-node": {
27
24
  "files": true,
28
25
  "transpileOnly": false
29
26
  },
30
- "include": ["./**/*.ts", "lib/**/*.json", "./**/*.tsx"],
31
- "exclude": ["node_modules", "**/thorn", "**/support", "**/tmp"]
27
+ "include": ["lib/*.ts"]
32
28
  }
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.0.8
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bogdan Gusiev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-21 00:00:00.000000000 Z
11
+ date: 2021-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 3.0.0
47
+ version: 3.10.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 3.0.0
54
+ version: 3.10.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -183,6 +183,9 @@ files:
183
183
  - spec/js_routes/default_serializer_spec.rb
184
184
  - spec/js_routes/module_types/amd_spec.rb
185
185
  - spec/js_routes/module_types/cjs_spec.rb
186
+ - spec/js_routes/module_types/dts/routes.spec.d.ts
187
+ - spec/js_routes/module_types/dts/test.spec.ts
188
+ - spec/js_routes/module_types/dts_spec.rb
186
189
  - spec/js_routes/module_types/esm_spec.rb
187
190
  - spec/js_routes/module_types/umd_spec.rb
188
191
  - spec/js_routes/options_spec.rb
@@ -190,6 +193,7 @@ files:
190
193
  - spec/js_routes/zzz_last_post_rails_init_spec.rb
191
194
  - spec/spec_helper.rb
192
195
  - spec/support/routes.rb
196
+ - spec/tsconfig.json
193
197
  - tsconfig.json
194
198
  - yarn.lock
195
199
  homepage: http://github.com/railsware/js-routes