js-routes 2.0.8 → 2.2.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.
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;
76
+
77
+ type PartsTable = Record<string, { r?: boolean; d?: OptionalRouteParameter }>;
41
78
 
42
- type ModuleType = "CJS" | "AMD" | "UMD" | "ESM" | "NIL";
79
+ type ModuleType = "CJS" | "AMD" | "UMD" | "ESM" | "DTS" | "NIL";
43
80
 
44
81
  declare const RubyVariables: {
45
82
  PREFIX: string;
@@ -92,8 +129,9 @@ RubyVariables.WRAPPER(
92
129
  }[keyof RouteNodes];
93
130
 
94
131
  const Root = that;
132
+ const isBroswer = typeof window !== "undefined";
95
133
  type ModuleDefinition = {
96
- define: (routes: unknown) => void;
134
+ define: (routes: RouterExposedMethods) => void;
97
135
  isSupported: () => boolean;
98
136
  };
99
137
  const ModuleReferences: Record<ModuleType, ModuleDefinition> = {
@@ -152,7 +190,16 @@ RubyVariables.WRAPPER(
152
190
  Utils.namespace(Root, RubyVariables.NAMESPACE, routes);
153
191
  },
154
192
  isSupported() {
155
- return !!Root;
193
+ return !RubyVariables.NAMESPACE || !!Root;
194
+ },
195
+ },
196
+ DTS: {
197
+ // Acts the same as ESM
198
+ define(routes) {
199
+ ModuleReferences.ESM.define(routes);
200
+ },
201
+ isSupported() {
202
+ return ModuleReferences.ESM.isSupported();
156
203
  },
157
204
  },
158
205
  };
@@ -225,16 +272,16 @@ RubyVariables.WRAPPER(
225
272
  return result.join("&");
226
273
  }
227
274
 
228
- serialize(object: unknown): string {
275
+ serialize(object: Serializable): string {
229
276
  return this.configuration.serializer(object);
230
277
  }
231
278
 
232
279
  extract_options(
233
280
  number_of_params: number,
234
- args: RouteParameter[]
281
+ args: OptionalRouteParameter[]
235
282
  ): {
236
- args: RouteParameter[];
237
- options: KeywordUrlOptions & RouteParameters;
283
+ args: OptionalRouteParameter[];
284
+ options: RouteOptions;
238
285
  } {
239
286
  const last_el = args[args.length - 1];
240
287
  if (
@@ -247,32 +294,27 @@ RubyVariables.WRAPPER(
247
294
  }
248
295
  return {
249
296
  args: args.slice(0, args.length - 1),
250
- options: last_el as KeywordUrlOptions & RouteParameters,
297
+ options: (last_el as any) as RouteOptions,
251
298
  };
252
299
  } else {
253
300
  return { args, options: {} };
254
301
  }
255
302
  }
256
303
 
257
- looks_like_serialized_model(
258
- object: any
259
- ): object is
260
- | { id: unknown }
261
- | { to_param: unknown }
262
- | { toParam: unknown } {
304
+ looks_like_serialized_model(object: any): object is ModelRouteParameter {
263
305
  return (
264
306
  this.is_object(object) &&
265
- !object[this.configuration.special_options_key] &&
307
+ !(this.configuration.special_options_key in object) &&
266
308
  ("id" in object || "to_param" in object || "toParam" in object)
267
309
  );
268
310
  }
269
311
 
270
- path_identifier(object: unknown): string {
312
+ path_identifier(object: QueryRouteParameter): string {
271
313
  const result = this.unwrap_path_identifier(object);
272
314
  return this.is_nullable(result) || result === false ? "" : "" + result;
273
315
  }
274
316
 
275
- unwrap_path_identifier(object: any): unknown {
317
+ unwrap_path_identifier(object: QueryRouteParameter): unknown {
276
318
  let result: any = object;
277
319
  if (!this.is_object(object)) {
278
320
  return object;
@@ -293,7 +335,7 @@ RubyVariables.WRAPPER(
293
335
  parts: string[],
294
336
  required_params: string[],
295
337
  default_options: RouteParameters,
296
- call_arguments: RouteParameter[]
338
+ call_arguments: OptionalRouteParameter[]
297
339
  ): {
298
340
  keyword_parameters: KeywordUrlOptions;
299
341
  query_parameters: RouteParameters;
@@ -307,7 +349,9 @@ RubyVariables.WRAPPER(
307
349
  throw new Error("Too many parameters provided for path");
308
350
  }
309
351
  let use_all_parts = args.length > required_params.length;
310
- const parts_options: RouteParameters = {};
352
+ const parts_options: RouteParameters = {
353
+ ...this.configuration.default_url_options,
354
+ };
311
355
  for (const key in options) {
312
356
  const value = options[key];
313
357
  if (!hasProp(options, key)) continue;
@@ -357,7 +401,7 @@ RubyVariables.WRAPPER(
357
401
  default_options: RouteParameters,
358
402
  route: RouteTree,
359
403
  absolute: boolean,
360
- args: RouteParameter[]
404
+ args: OptionalRouteParameter[]
361
405
  ): string {
362
406
  const {
363
407
  keyword_parameters,
@@ -467,9 +511,9 @@ RubyVariables.WRAPPER(
467
511
  }
468
512
 
469
513
  encode_segment(segment: string): string {
470
- return segment.replace(UriEncoderSegmentRegex, function (str) {
471
- return encodeURIComponent(str);
472
- });
514
+ return segment.replace(UriEncoderSegmentRegex, (str) =>
515
+ encodeURIComponent(str)
516
+ );
473
517
  }
474
518
 
475
519
  is_optional_node(node: NodeTypes): boolean {
@@ -550,7 +594,7 @@ RubyVariables.WRAPPER(
550
594
  default_options[part] = value;
551
595
  }
552
596
  }
553
- const result = (...args: RouteParameter[]): string => {
597
+ const result = (...args: OptionalRouteParameter[]): string => {
554
598
  return this.build_route(
555
599
  parts,
556
600
  required_params,
@@ -564,7 +608,7 @@ RubyVariables.WRAPPER(
564
608
  result.toString = () => {
565
609
  return this.build_path_spec(route_spec);
566
610
  };
567
- return result;
611
+ return result as any;
568
612
  }
569
613
 
570
614
  route_url(route_defaults: KeywordUrlOptions): string {
@@ -583,31 +627,18 @@ RubyVariables.WRAPPER(
583
627
  return protocol + "://" + subdomain + hostname + port;
584
628
  }
585
629
 
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
- }
630
+ current_host(): string {
631
+ return (isBroswer && window?.location?.hostname) || "";
596
632
  }
597
633
 
598
634
  current_protocol(): string {
599
- if (this.has_location() && window.location.protocol !== "") {
600
- return window.location.protocol.replace(/:$/, "");
601
- } else {
602
- return "http";
603
- }
635
+ return (
636
+ (isBroswer && window?.location?.protocol?.replace(/:$/, "")) || "http"
637
+ );
604
638
  }
639
+
605
640
  current_port(): string {
606
- if (this.has_location() && window.location.port !== "") {
607
- return window.location.port;
608
- } else {
609
- return "";
610
- }
641
+ return (isBroswer && window?.location?.port) || "";
611
642
  }
612
643
 
613
644
  is_object(value: unknown): value is Record<string, unknown> {
@@ -633,17 +664,17 @@ RubyVariables.WRAPPER(
633
664
  object: any,
634
665
  namespace: string | null | undefined,
635
666
  routes: unknown
636
- ): unknown {
667
+ ): void {
637
668
  const parts = namespace?.split(".") || [];
638
669
  if (parts.length === 0) {
639
- return routes;
670
+ return;
640
671
  }
641
672
  for (let index = 0; index < parts.length; index++) {
642
673
  const part = parts[index];
643
674
  if (index < parts.length - 1) {
644
675
  object = object[part] || (object[part] = {});
645
676
  } else {
646
- return (object[part] = routes);
677
+ object[part] = routes;
647
678
  }
648
679
  }
649
680
  }
@@ -694,7 +725,7 @@ RubyVariables.WRAPPER(
694
725
  config: (): Configuration => {
695
726
  return Utils.config();
696
727
  },
697
- serialize: (object: unknown): string => {
728
+ serialize: (object: Serializable): string => {
698
729
  return Utils.serialize(object);
699
730
  },
700
731
  ...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,11 @@
1
+ module.exports = {
2
+ module: {
3
+ rules: [
4
+ {
5
+ test: /\.erb$/,
6
+ enforce: 'pre',
7
+ loader: 'rails-erb-loader'
8
+ },
9
+ ]
10
+ }
11
+ };
@@ -0,0 +1,5 @@
1
+ JsRoutes.setup do |c|
2
+ # Setup your JS module system:
3
+ # ESM, CJS, AMD, UMD or nil
4
+ # c.module_type = "ESM"
5
+ end
@@ -0,0 +1 @@
1
+ <%= JsRoutes.generate %>
@@ -3,11 +3,12 @@ require "spec_helper"
3
3
  describe JsRoutes, "compatibility with AMD/require.js" do
4
4
 
5
5
  before(:each) do
6
- evaljs("window.GlobalCheck = {};")
7
- evaljs("window.define = function (requirs, callback) { window.GlobalCheck['js-routes'] = callback.call(this); return window.GlobalCheck['js-routes']; };")
8
- evaljs("window.define.amd = { jQuery: true };")
6
+ evaljs("var global = this;", {force: true})
7
+ evaljs("global.GlobalCheck = {};")
8
+ evaljs("global.define = function (requirs, callback) { global.GlobalCheck['js-routes'] = callback.call(this); return global.GlobalCheck['js-routes']; };")
9
+ evaljs("global.define.amd = { jQuery: true };")
9
10
  strRequire =<<EOF
10
- window.require = function (r, callback) {
11
+ global.require = function (r, callback) {
11
12
  var allArgs, i;
12
13
 
13
14
  allArgs = (function() {
@@ -15,7 +16,7 @@ describe JsRoutes, "compatibility with AMD/require.js" do
15
16
  _results = [];
16
17
  for (_i = 0, _len = r.length; _i < _len; _i++) {
17
18
  i = r[_i];
18
- _results.push(window.GlobalCheck[i]);
19
+ _results.push(global.GlobalCheck[i]);
19
20
  }
20
21
  return _results;
21
22
  })();
@@ -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