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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/Readme.md +146 -86
- data/js-routes.gemspec +1 -1
- data/lib/js_routes/generators/middleware.rb +33 -0
- data/lib/js_routes/generators/webpacker.rb +32 -0
- data/lib/js_routes/middleware.rb +36 -0
- data/lib/js_routes/version.rb +1 -1
- data/lib/js_routes.rb +172 -97
- data/lib/routes.d.ts +33 -11
- data/lib/routes.js +24 -29
- data/lib/routes.ts +88 -57
- data/lib/tasks/js_routes.rake +8 -2
- data/lib/templates/erb.js +11 -0
- data/lib/templates/initializer.rb +5 -0
- data/lib/templates/routes.js.erb +1 -0
- data/spec/js_routes/module_types/amd_spec.rb +6 -5
- data/spec/js_routes/module_types/dts/routes.spec.d.ts +114 -0
- data/spec/js_routes/module_types/dts/test.spec.ts +56 -0
- data/spec/js_routes/module_types/dts_spec.rb +111 -0
- data/spec/js_routes/module_types/nil_spec.rb +86 -0
- data/spec/js_routes/module_types/umd_spec.rb +1 -1
- data/spec/js_routes/options_spec.rb +33 -51
- data/spec/js_routes/zzz_last_post_rails_init_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -2
- data/spec/support/routes.rb +1 -1
- data/spec/tsconfig.json +4 -0
- data/tsconfig.json +3 -7
- metadata +15 -4
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
|
7
|
-
type
|
8
|
-
type
|
9
|
-
type
|
10
|
-
|
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
|
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:
|
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:
|
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:
|
281
|
+
args: OptionalRouteParameter[]
|
235
282
|
): {
|
236
|
-
args:
|
237
|
-
options:
|
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
|
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
|
-
!
|
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:
|
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:
|
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:
|
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:
|
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,
|
471
|
-
|
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:
|
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
|
-
|
587
|
-
return
|
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
|
-
|
600
|
-
|
601
|
-
|
602
|
-
return "http";
|
603
|
-
}
|
635
|
+
return (
|
636
|
+
(isBroswer && window?.location?.protocol?.replace(/:$/, "")) || "http"
|
637
|
+
);
|
604
638
|
}
|
639
|
+
|
605
640
|
current_port(): string {
|
606
|
-
|
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
|
-
):
|
667
|
+
): void {
|
637
668
|
const parts = namespace?.split(".") || [];
|
638
669
|
if (parts.length === 0) {
|
639
|
-
return
|
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
|
-
|
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:
|
728
|
+
serialize: (object: Serializable): string => {
|
698
729
|
return Utils.serialize(object);
|
699
730
|
},
|
700
731
|
...RubyVariables.ROUTES_OBJECT,
|
data/lib/tasks/js_routes.rake
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
namespace :js do
|
2
|
-
desc "Make a js file
|
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 @@
|
|
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("
|
7
|
-
evaljs("
|
8
|
-
evaljs("
|
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
|
-
|
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(
|
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
|