js-routes 2.0.8 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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