enroute 0.0.1 → 0.0.2
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/.github/FUNDING.yml +1 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +3 -4
- data/.tool-versions +1 -1
- data/README.md +41 -2
- data/enroute.gemspec +3 -0
- data/lib/enroute/cli.rb +8 -1
- data/lib/enroute/export.rb +38 -35
- data/lib/enroute/routes.rb +30 -6
- data/lib/enroute/template.ts.erb +2 -15
- data/lib/enroute/version.rb +1 -1
- data/lib/enroute.rb +2 -0
- metadata +36 -8
- data/yarn.lock +0 -3909
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a1933a0b54db509a086908e62c6c1c0cd32baa72fbeba4f2b19e180f179b7e0
|
4
|
+
data.tar.gz: 65cd118dfb50f62b13b43fc2fe6ec95f3ada98d0d15947a7261f2858ae8b4b83
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24398ef1734fe1964932aee1c3e5ea29efe4ff73a11e99612eadcc55579b31b0c8611e54e4a46a030059efbfcc597b4372d97fc856c62c420fb0dcb61f92419e
|
7
|
+
data.tar.gz: 23d765635d12a58a14a263cc5cbf595d814b4443a46fceef1fab4cd61b93519e86b0d2e74e526639abd93749f0e1764a8a9409dec4dba73bf0267f7393e92407
|
data/.github/FUNDING.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
github: [fnando]
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/.tool-versions
CHANGED
@@ -1 +1 @@
|
|
1
|
-
nodejs
|
1
|
+
nodejs 16.7.0
|
data/README.md
CHANGED
@@ -25,16 +25,55 @@ All you have to do is call the `enroute` binary with the main file you want to
|
|
25
25
|
load and a output path.
|
26
26
|
|
27
27
|
```console
|
28
|
-
$ bundle exec enroute --output ./app/frontend/scripts/config/routes.ts
|
28
|
+
$ bundle exec enroute export --output ./app/frontend/scripts/config/routes.ts
|
29
29
|
```
|
30
30
|
|
31
31
|
By default, `<pwd>/config/environment.rb` will be loaded. If you want to use a
|
32
32
|
different file, use the `--require` switch.
|
33
33
|
|
34
34
|
```console
|
35
|
-
$ bundle exec enroute --require ./different-file.rb --output ./routes.ts
|
35
|
+
$ bundle exec enroute export --require ./different-file.rb --output ./routes.ts
|
36
36
|
```
|
37
37
|
|
38
|
+
You can also ignore routes by using a config file.
|
39
|
+
|
40
|
+
```console
|
41
|
+
$ bundle exec enroute export --output ./app/frontend/scripts/config/routes.ts --config ./config/enroute.yml
|
42
|
+
```
|
43
|
+
|
44
|
+
The config file must look like this:
|
45
|
+
|
46
|
+
```yaml
|
47
|
+
---
|
48
|
+
ignore:
|
49
|
+
- route_name
|
50
|
+
```
|
51
|
+
|
52
|
+
There's also a `:only` option that will include only the matching named routes.
|
53
|
+
|
54
|
+
```yaml
|
55
|
+
---
|
56
|
+
only:
|
57
|
+
- route_name
|
58
|
+
```
|
59
|
+
|
60
|
+
By default, route params will be typed as `any`. To add a custom typing
|
61
|
+
annotation, you can use the `typings` key on the configuration file. Imagine you
|
62
|
+
have the route `get "settings/edit(/:section)" => "", as: "edit_settings"`; you
|
63
|
+
can have a config file like this:
|
64
|
+
|
65
|
+
```yaml
|
66
|
+
---
|
67
|
+
typings:
|
68
|
+
_default:
|
69
|
+
format: '"html" | "json"'
|
70
|
+
|
71
|
+
edit_settings:
|
72
|
+
section: string
|
73
|
+
```
|
74
|
+
|
75
|
+
### Importing helpers on TypeScript
|
76
|
+
|
38
77
|
You can then import any route that's been exported. Parameters are positional.
|
39
78
|
|
40
79
|
```typescript
|
data/enroute.gemspec
CHANGED
@@ -7,6 +7,7 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.version = Enroute::VERSION
|
8
8
|
spec.authors = ["Nando Vieira"]
|
9
9
|
spec.email = ["me@fnando.com"]
|
10
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
|
10
11
|
|
11
12
|
spec.summary = "Export Rails routes to TypeScript definitions"
|
12
13
|
spec.description = spec.summary
|
@@ -27,9 +28,11 @@ Gem::Specification.new do |spec|
|
|
27
28
|
spec.executables = spec.files.grep(%r{^exe/}) {|f| File.basename(f) }
|
28
29
|
spec.require_paths = ["lib"]
|
29
30
|
|
31
|
+
spec.add_dependency "activesupport"
|
30
32
|
spec.add_dependency "thor"
|
31
33
|
spec.add_development_dependency "minitest"
|
32
34
|
spec.add_development_dependency "minitest-utils"
|
35
|
+
spec.add_development_dependency "pry-meta"
|
33
36
|
spec.add_development_dependency "rails"
|
34
37
|
spec.add_development_dependency "rake"
|
35
38
|
spec.add_development_dependency "rubocop"
|
data/lib/enroute/cli.rb
CHANGED
@@ -24,12 +24,19 @@ module Enroute
|
|
24
24
|
required: true,
|
25
25
|
aliases: :o
|
26
26
|
|
27
|
+
option :config,
|
28
|
+
type: :string,
|
29
|
+
required: false,
|
30
|
+
aliases: :c,
|
31
|
+
default: File.join(Dir.pwd, "config/enroute.yml")
|
32
|
+
|
27
33
|
def export
|
28
34
|
require_path = File.expand_path(options["require"])
|
29
35
|
output_path = File.expand_path(options["output"])
|
36
|
+
config_path = File.expand_path(options["config"])
|
30
37
|
|
31
38
|
require require_path
|
32
|
-
Export.call(output_path)
|
39
|
+
Export.call(output_path, config_path)
|
33
40
|
end
|
34
41
|
end
|
35
42
|
end
|
data/lib/enroute/export.rb
CHANGED
@@ -1,25 +1,36 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Enroute
|
4
|
-
|
5
|
-
|
4
|
+
class Export
|
5
|
+
attr_reader :output_path, :config_path
|
6
6
|
|
7
|
-
def call(output_path)
|
8
|
-
|
7
|
+
def self.call(output_path, config_path)
|
8
|
+
new(output_path, config_path).call
|
9
|
+
end
|
9
10
|
|
10
|
-
|
11
|
+
def initialize(output_path, config_path)
|
12
|
+
@output_path = output_path
|
13
|
+
@config_path = config_path
|
14
|
+
end
|
15
|
+
|
16
|
+
def config
|
17
|
+
@config ||= if File.file?(config_path)
|
18
|
+
ActiveSupport::HashWithIndifferentAccess.new(
|
19
|
+
YAML.load_file(config_path)
|
20
|
+
)
|
21
|
+
else
|
22
|
+
{}
|
23
|
+
end
|
11
24
|
end
|
12
25
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
router_type: routes.map {|route| build_ts_route_definition(route) }.join
|
18
|
-
}
|
26
|
+
def call
|
27
|
+
FileUtils.mkdir_p(File.dirname(output_path))
|
28
|
+
|
29
|
+
write_template(output_path)
|
19
30
|
end
|
20
31
|
|
21
32
|
def routes
|
22
|
-
Routes.call
|
33
|
+
@routes ||= Routes.call(config)
|
23
34
|
end
|
24
35
|
|
25
36
|
def write_template(output_path)
|
@@ -30,50 +41,42 @@ module Enroute
|
|
30
41
|
|
31
42
|
def route_functions
|
32
43
|
routes
|
33
|
-
.
|
34
|
-
.map {|route, index| build_ts_function(route, index) }
|
44
|
+
.map {|route| build_ts_route_function(route) }
|
35
45
|
.join("\n\n")
|
36
46
|
end
|
37
47
|
|
38
|
-
def
|
39
|
-
routes.map {|route|
|
40
|
-
end
|
41
|
-
|
42
|
-
def type_definitions
|
43
|
-
routes.map {|route| build_ts_definition(route) }.join("\n")
|
48
|
+
def handler_functions
|
49
|
+
routes.map {|route| build_ts_handler_function(route) }.join("\n\n")
|
44
50
|
end
|
45
51
|
|
46
52
|
def render_template
|
47
53
|
ERB.new(File.read("#{__dir__}/template.ts.erb")).result binding
|
48
54
|
end
|
49
55
|
|
50
|
-
def build_ts_definition(route)
|
51
|
-
[
|
52
|
-
"export interface #{route[:typeName]} extends RouteHandler {",
|
53
|
-
" (#{build_ts_args_definition(route)}): string;",
|
54
|
-
"}\n"
|
55
|
-
].join("\n")
|
56
|
-
end
|
57
|
-
|
58
56
|
def build_ts_args_definition(route)
|
59
57
|
route[:segments].map do |segment|
|
58
|
+
type = route.dig(:typings, segment)&.chomp ||
|
59
|
+
config.dig(:typings, :_default, segment)&.chomp ||
|
60
|
+
"any"
|
61
|
+
|
60
62
|
optional = route[:requiredSegments].include?(segment) ? "" : "?"
|
61
|
-
"#{segment.camelize(:lower)}#{optional}:
|
63
|
+
"#{segment.camelize(:lower)}#{optional}: #{type}"
|
62
64
|
end.join(", ")
|
63
65
|
end
|
64
66
|
|
65
|
-
def
|
67
|
+
def build_ts_handler_function(route)
|
68
|
+
args = JSON.pretty_generate(route.except(:typings))
|
69
|
+
%[const #{route[:name]}Handler = buildRoute(#{args});]
|
70
|
+
end
|
71
|
+
|
72
|
+
def build_ts_route_function(route)
|
66
73
|
args = build_ts_args_definition(route)
|
67
74
|
segments = route[:segments].map {|segment| segment.camelize(:lower) }
|
68
75
|
|
69
76
|
[
|
70
77
|
%[export const #{route[:name]}Url = (#{args}): string =>],
|
71
|
-
%[
|
78
|
+
%[ #{route[:name]}Handler(#{segments.join(', ')});]
|
72
79
|
].join("\n")
|
73
80
|
end
|
74
|
-
|
75
|
-
def build_ts_route_definition(route)
|
76
|
-
%[\n #{route[:name]}: #{route[:typeName]};]
|
77
|
-
end
|
78
81
|
end
|
79
82
|
end
|
data/lib/enroute/routes.rb
CHANGED
@@ -1,8 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Enroute
|
4
|
-
|
5
|
-
|
4
|
+
class Routes
|
5
|
+
attr_reader :config
|
6
|
+
|
7
|
+
def self.call(config = {})
|
8
|
+
new(config).call
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(config)
|
12
|
+
@config = config
|
13
|
+
end
|
6
14
|
|
7
15
|
def call
|
8
16
|
grouped_routes.each_with_object([]) do |(_pattern, routes), buffer|
|
@@ -17,12 +25,12 @@ module Enroute
|
|
17
25
|
def build_payload(route)
|
18
26
|
{
|
19
27
|
name: route.name.camelize(:lower),
|
20
|
-
typeName: "#{route.name.camelize}RouteHandler",
|
21
28
|
incomingPattern: camelize_pattern(route),
|
22
29
|
outgoingPattern: route.ast.to_s,
|
23
30
|
method: reduce_methods(routes),
|
24
31
|
segments: route.segments,
|
25
|
-
requiredSegments: route.path.required_names
|
32
|
+
requiredSegments: route.path.required_names,
|
33
|
+
typings: config.dig(:typings, route.name) || {}
|
26
34
|
}
|
27
35
|
end
|
28
36
|
|
@@ -48,8 +56,24 @@ module Enroute
|
|
48
56
|
end
|
49
57
|
|
50
58
|
def filtered_routes
|
51
|
-
|
52
|
-
|
59
|
+
only_conditions = config.fetch(:only, [])
|
60
|
+
|
61
|
+
# If `:only` has at least one item, then select matching routes.
|
62
|
+
# Otherwise, use all routes.
|
63
|
+
selected_routes = if only_conditions.empty?
|
64
|
+
routes
|
65
|
+
else
|
66
|
+
routes.select do |route|
|
67
|
+
only_conditions.include?(route.name)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Filter out unnamed routes, Rails' internal routes, and anything present
|
72
|
+
# on `:ignore`.
|
73
|
+
selected_routes.reject do |route|
|
74
|
+
route.name.nil? ||
|
75
|
+
route.name.match?(/rails|script/) ||
|
76
|
+
config.fetch(:ignore, []).include?(route.name)
|
53
77
|
end
|
54
78
|
end
|
55
79
|
|
data/lib/enroute/template.ts.erb
CHANGED
@@ -90,17 +90,10 @@ function generate(route: Route): RouteHelper {
|
|
90
90
|
};
|
91
91
|
}
|
92
92
|
|
93
|
-
|
94
|
-
export type ArrayType = AnyObject[];
|
95
|
-
export type AnyObject = PrimitiveType | ArrayType | ObjectType | any;
|
96
|
-
|
97
|
-
export interface ObjectType {
|
98
|
-
[key: string]: PrimitiveType | ArrayType | ObjectType;
|
99
|
-
}
|
93
|
+
type PrimitiveType = number | string | null | undefined | boolean;
|
100
94
|
|
101
95
|
export interface Route {
|
102
96
|
name: string;
|
103
|
-
typeName: string;
|
104
97
|
pattern?: string;
|
105
98
|
method: string[];
|
106
99
|
segments: string[];
|
@@ -118,12 +111,6 @@ export type RouteHandler = RouteHelper & {
|
|
118
111
|
underscore: RouteHelper;
|
119
112
|
};
|
120
113
|
|
121
|
-
<%=
|
122
|
-
|
123
|
-
export const routes: Route[] = <%= JSON.pretty_generate(routes) %>;
|
124
|
-
|
125
|
-
export const routeHandlers: RouteHandler[] = [
|
126
|
-
<%= routes.each_with_index.map {|route, index| %[ buildRoute(routes[#{index}]) as #{route[:typeName]},] }.join("\n") %>
|
127
|
-
];
|
114
|
+
<%= handler_functions %>
|
128
115
|
|
129
116
|
<%= route_functions %>
|
data/lib/enroute/version.rb
CHANGED
data/lib/enroute.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: enroute
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nando Vieira
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: thor
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +66,20 @@ dependencies:
|
|
52
66
|
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry-meta
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: rails
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -117,6 +145,7 @@ extensions: []
|
|
117
145
|
extra_rdoc_files: []
|
118
146
|
files:
|
119
147
|
- ".eslintrc.json"
|
148
|
+
- ".github/FUNDING.yml"
|
120
149
|
- ".gitignore"
|
121
150
|
- ".prettierrc.js"
|
122
151
|
- ".rubocop.yml"
|
@@ -138,7 +167,6 @@ files:
|
|
138
167
|
- lib/enroute/version.rb
|
139
168
|
- package.json
|
140
169
|
- tsconfig.json
|
141
|
-
- yarn.lock
|
142
170
|
homepage: https://github.com/fnando/enroute
|
143
171
|
licenses:
|
144
172
|
- MIT
|
@@ -146,7 +174,7 @@ metadata:
|
|
146
174
|
homepage_uri: https://github.com/fnando/enroute
|
147
175
|
source_code_uri: https://github.com/fnando/enroute
|
148
176
|
changelog_uri: https://github.com/fnando/enroute
|
149
|
-
post_install_message:
|
177
|
+
post_install_message:
|
150
178
|
rdoc_options: []
|
151
179
|
require_paths:
|
152
180
|
- lib
|
@@ -154,15 +182,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
154
182
|
requirements:
|
155
183
|
- - ">="
|
156
184
|
- !ruby/object:Gem::Version
|
157
|
-
version:
|
185
|
+
version: 2.7.0
|
158
186
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
159
187
|
requirements:
|
160
188
|
- - ">="
|
161
189
|
- !ruby/object:Gem::Version
|
162
190
|
version: '0'
|
163
191
|
requirements: []
|
164
|
-
rubygems_version: 3.
|
165
|
-
signing_key:
|
192
|
+
rubygems_version: 3.2.22
|
193
|
+
signing_key:
|
166
194
|
specification_version: 4
|
167
195
|
summary: Export Rails routes to TypeScript definitions
|
168
196
|
test_files: []
|