typespec_from_serializers 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 58c9803235729fabc83ae742e83822906d3ed88746e2c40f7d04d7368409a5cb
|
|
4
|
+
data.tar.gz: de245ba8d20d6b695af332f886c8b0b83a491cd563364a2c06f000c90726739e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: efc632aa512a2fec97c35bde59de42c1516ec23d4231be04cbc3238ca5a1bc7756c495cb9b7efcbb5a0209aade99bd6096b04229b0b6bbc4b1afae58a5b4b62b
|
|
7
|
+
data.tar.gz: 2a2fb5ca8cf367d6a22649538af11e2ee690256522caca1b63de0639d8e5b64fb8d6d5af1453ac7604a2632c439b3132652a4b906d16b0cac76c0ac4c87150f3
|
data/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,21 @@ module TypeSpecFromSerializers
|
|
|
30
30
|
module Linting
|
|
31
31
|
extend self
|
|
32
32
|
|
|
33
|
+
@warning_count = 0
|
|
34
|
+
|
|
35
|
+
def reset_count
|
|
36
|
+
@warning_count = 0
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def warning_count
|
|
40
|
+
@warning_count
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def print_summary
|
|
44
|
+
return if @warning_count == 0
|
|
45
|
+
puts "\nTypeSpec generation completed with #{@warning_count} lint warning#{'s' unless @warning_count == 1}"
|
|
46
|
+
end
|
|
47
|
+
|
|
33
48
|
# Internal: Lints for missing parameter types
|
|
34
49
|
def missing_param_types(controller, route, path_param_names, param_types, config)
|
|
35
50
|
return unless enabled?(config.linting, :missing_param_types)
|
|
@@ -37,6 +52,7 @@ module TypeSpecFromSerializers
|
|
|
37
52
|
missing_path_params = path_param_names.select { |name| !param_types.key?(name) }
|
|
38
53
|
|
|
39
54
|
unless missing_path_params.empty?
|
|
55
|
+
@warning_count += 1
|
|
40
56
|
location = "#{controller.camelize}#{config.controller_suffix}##{route[:action]}"
|
|
41
57
|
warn "TypeSpec Lint: Missing type for path parameter(s) #{missing_path_params.join(', ')} in #{location} (#{route[:method]} #{route[:path]}). Defaulting to 'string'."
|
|
42
58
|
end
|
|
@@ -47,6 +63,7 @@ module TypeSpecFromSerializers
|
|
|
47
63
|
return unless enabled?(config.linting, :unknown_response_types)
|
|
48
64
|
|
|
49
65
|
if response_type == "unknown"
|
|
66
|
+
@warning_count += 1
|
|
50
67
|
location = "#{controller.camelize}#{config.controller_suffix}##{route[:action]}"
|
|
51
68
|
warn "TypeSpec Lint: Unknown response type for #{location} (#{route[:method]} #{route[:path]}). Consider adding a serializer or explicit type annotation."
|
|
52
69
|
end
|
|
@@ -57,6 +74,7 @@ module TypeSpecFromSerializers
|
|
|
57
74
|
return unless enabled?(config.linting, :missing_documentation) && config.extract_docs
|
|
58
75
|
|
|
59
76
|
if doc.nil?
|
|
77
|
+
@warning_count += 1
|
|
60
78
|
location = "#{controller.camelize}#{config.controller_suffix}##{route[:action]}"
|
|
61
79
|
warn "TypeSpec Lint: Missing documentation for #{location} (#{route[:method]} #{route[:path]}). Consider adding an RDoc comment."
|
|
62
80
|
end
|
|
@@ -68,6 +86,7 @@ module TypeSpecFromSerializers
|
|
|
68
86
|
|
|
69
87
|
duplicates = name_counts.select { |_, count| count > 1 }
|
|
70
88
|
duplicates.each do |action, count|
|
|
89
|
+
@warning_count += 1
|
|
71
90
|
ops = operations.select { |op| op.action == action }
|
|
72
91
|
methods = ops.map { |op| op.method }.join(', ')
|
|
73
92
|
warn "TypeSpec Lint: Action '#{action}' used for multiple routes (#{methods}). Using method suffix to differentiate."
|
|
@@ -79,6 +98,7 @@ module TypeSpecFromSerializers
|
|
|
79
98
|
return unless enabled?(config.linting, :type_inference_failures)
|
|
80
99
|
|
|
81
100
|
if property.type.nil? && explicit_type.nil?
|
|
101
|
+
@warning_count += 1
|
|
82
102
|
warn "TypeSpec Lint: Could not infer type for '#{property.name}' in #{serializer_name}. Consider adding explicit type annotation."
|
|
83
103
|
end
|
|
84
104
|
end
|
|
@@ -598,6 +618,8 @@ module TypeSpecFromSerializers
|
|
|
598
618
|
|
|
599
619
|
# Public: Generates code for all serializers in the app.
|
|
600
620
|
def generate(force: ENV["SERIALIZER_TYPESPEC_FORCE"])
|
|
621
|
+
Linting.reset_count
|
|
622
|
+
|
|
601
623
|
@force_generation = force
|
|
602
624
|
clean_output_dir if force && config.output_dir.exist?
|
|
603
625
|
|
|
@@ -614,6 +636,8 @@ module TypeSpecFromSerializers
|
|
|
614
636
|
generate_model_for(serializer)
|
|
615
637
|
end
|
|
616
638
|
|
|
639
|
+
Linting.print_summary
|
|
640
|
+
|
|
617
641
|
{serializers: serializers, controllers: controllers}
|
|
618
642
|
end
|
|
619
643
|
|
|
@@ -763,7 +787,7 @@ module TypeSpecFromSerializers
|
|
|
763
787
|
path: path,
|
|
764
788
|
response_type: response_type,
|
|
765
789
|
route_name: route_name,
|
|
766
|
-
param_types: route.defaults[:
|
|
790
|
+
param_types: route.defaults[:__typespec_types] || {},
|
|
767
791
|
}
|
|
768
792
|
end
|
|
769
793
|
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "action_dispatch/routing/mapper"
|
|
4
|
+
require "action_dispatch/journey/route"
|
|
5
|
+
|
|
6
|
+
# Internal: Minimal surgical patches to ActionDispatch routing for TypeSpec metadata support.
|
|
7
|
+
#
|
|
8
|
+
# This module patches Rails routing to support the `type:` parameter for specifying
|
|
9
|
+
# path parameter types without interfering with Rails' route matching or URL generation.
|
|
10
|
+
#
|
|
11
|
+
# The type metadata is stored in route defaults under the :__typespec_types key and
|
|
12
|
+
# explicitly excluded from route requirements to prevent it from affecting routing behavior.
|
|
13
|
+
#
|
|
14
|
+
# Examples
|
|
15
|
+
#
|
|
16
|
+
# # In routes.rb
|
|
17
|
+
# resources :users, type: { id: Integer }
|
|
18
|
+
# get '/posts/:id', to: 'posts#show', type: { id: Integer }
|
|
19
|
+
#
|
|
20
|
+
# The patches work at three interception points:
|
|
21
|
+
# 1. Mapper::Base#match - for GET/POST/PATCH/etc methods
|
|
22
|
+
# 2. Mapper::Resources#resources - for resources/resource methods
|
|
23
|
+
# 3. Journey::Route#requirements - filters metadata from route requirements
|
|
24
|
+
module TypeSpecFromSerializers
|
|
25
|
+
# Internal: Shared logic for moving type metadata from options to defaults.
|
|
26
|
+
module RoutingPatchHelpers
|
|
27
|
+
module_function
|
|
28
|
+
|
|
29
|
+
# Internal: Moves type: parameter from route options to defaults[:__typespec_types].
|
|
30
|
+
#
|
|
31
|
+
# This ensures type metadata is stored but doesn't interfere with routing.
|
|
32
|
+
#
|
|
33
|
+
# options - Hash of route options (will be modified in place)
|
|
34
|
+
#
|
|
35
|
+
# Returns the modified options Hash
|
|
36
|
+
def move_type_to_defaults!(options)
|
|
37
|
+
return options unless options.key?(:type)
|
|
38
|
+
|
|
39
|
+
types = options.delete(:type)
|
|
40
|
+
options[:defaults] = (options[:defaults] || {}).merge(__typespec_types: types)
|
|
41
|
+
options
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Internal: Patches ActionDispatch::Routing::Mapper::Base to intercept match method.
|
|
46
|
+
#
|
|
47
|
+
# Intercepts the low-level match method used by get, post, patch, delete, etc.
|
|
48
|
+
module MapperPatch
|
|
49
|
+
def match(path, *rest, &block)
|
|
50
|
+
options = rest.last.is_a?(Hash) ? rest.pop.dup : {}
|
|
51
|
+
RoutingPatchHelpers.move_type_to_defaults!(options)
|
|
52
|
+
|
|
53
|
+
rest.push(options) unless options.empty?
|
|
54
|
+
super(path, *rest, &block)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Internal: Patches ActionDispatch::Routing::Mapper::Resources to intercept resources method.
|
|
59
|
+
#
|
|
60
|
+
# Intercepts the resources/resource DSL methods to support type: parameter.
|
|
61
|
+
module ResourcesPatch
|
|
62
|
+
def resources(*resources, &block)
|
|
63
|
+
options = resources.extract_options!
|
|
64
|
+
RoutingPatchHelpers.move_type_to_defaults!(options)
|
|
65
|
+
|
|
66
|
+
resources.push(options) unless options.empty?
|
|
67
|
+
super(*resources, &block)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Internal: Patches ActionDispatch::Journey::Route to filter type metadata from requirements.
|
|
72
|
+
#
|
|
73
|
+
# The requirements method is used for route matching and URL generation.
|
|
74
|
+
# We exclude :__typespec_types to ensure it doesn't affect routing behavior.
|
|
75
|
+
module RoutePatch
|
|
76
|
+
def requirements
|
|
77
|
+
super.except(:__typespec_types)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Apply patches to ActionDispatch
|
|
83
|
+
ActionDispatch::Routing::Mapper::Base.prepend(TypeSpecFromSerializers::MapperPatch)
|
|
84
|
+
ActionDispatch::Routing::Mapper::Resources.prepend(TypeSpecFromSerializers::ResourcesPatch)
|
|
85
|
+
ActionDispatch::Journey::Route.prepend(TypeSpecFromSerializers::RoutePatch)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: typespec_from_serializers
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Danila Poyarkov
|
|
@@ -320,6 +320,7 @@ files:
|
|
|
320
320
|
- lib/typespec_from_serializers/railtie.rb
|
|
321
321
|
- lib/typespec_from_serializers/rbi.rb
|
|
322
322
|
- lib/typespec_from_serializers/rdoc.rb
|
|
323
|
+
- lib/typespec_from_serializers/routing_patch.rb
|
|
323
324
|
- lib/typespec_from_serializers/runner.rb
|
|
324
325
|
- lib/typespec_from_serializers/sorbet.rb
|
|
325
326
|
- lib/typespec_from_serializers/version.rb
|