apiwork 0.0.0.pre → 0.1.1

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.
Files changed (202) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +2 -2
  3. data/README.md +117 -1
  4. data/Rakefile +5 -3
  5. data/app/controllers/apiwork/errors_controller.rb +13 -0
  6. data/app/controllers/apiwork/exports_controller.rb +22 -0
  7. data/lib/apiwork/abstractable.rb +26 -0
  8. data/lib/apiwork/adapter/base.rb +369 -0
  9. data/lib/apiwork/adapter/builder/api/base.rb +66 -0
  10. data/lib/apiwork/adapter/builder/contract/base.rb +86 -0
  11. data/lib/apiwork/adapter/capability/api/base.rb +51 -0
  12. data/lib/apiwork/adapter/capability/api/scope.rb +64 -0
  13. data/lib/apiwork/adapter/capability/base.rb +291 -0
  14. data/lib/apiwork/adapter/capability/contract/base.rb +37 -0
  15. data/lib/apiwork/adapter/capability/contract/scope.rb +110 -0
  16. data/lib/apiwork/adapter/capability/operation/base.rb +172 -0
  17. data/lib/apiwork/adapter/capability/operation/metadata_shape.rb +165 -0
  18. data/lib/apiwork/adapter/capability/result.rb +21 -0
  19. data/lib/apiwork/adapter/capability/runner.rb +56 -0
  20. data/lib/apiwork/adapter/capability/transformer/request/base.rb +72 -0
  21. data/lib/apiwork/adapter/capability/transformer/response/base.rb +45 -0
  22. data/lib/apiwork/adapter/registry.rb +16 -0
  23. data/lib/apiwork/adapter/serializer/error/base.rb +72 -0
  24. data/lib/apiwork/adapter/serializer/error/default/api_builder.rb +32 -0
  25. data/lib/apiwork/adapter/serializer/error/default.rb +37 -0
  26. data/lib/apiwork/adapter/serializer/resource/base.rb +84 -0
  27. data/lib/apiwork/adapter/serializer/resource/default/contract_builder.rb +209 -0
  28. data/lib/apiwork/adapter/serializer/resource/default.rb +39 -0
  29. data/lib/apiwork/adapter/standard/capability/filtering/api_builder.rb +75 -0
  30. data/lib/apiwork/adapter/standard/capability/filtering/constants.rb +37 -0
  31. data/lib/apiwork/adapter/standard/capability/filtering/contract_builder.rb +193 -0
  32. data/lib/apiwork/adapter/standard/capability/filtering/operation/filter/builder.rb +47 -0
  33. data/lib/apiwork/adapter/standard/capability/filtering/operation/filter/operator_builder.rb +36 -0
  34. data/lib/apiwork/adapter/standard/capability/filtering/operation/filter.rb +462 -0
  35. data/lib/apiwork/adapter/standard/capability/filtering/operation.rb +22 -0
  36. data/lib/apiwork/adapter/standard/capability/filtering/request_transformer.rb +47 -0
  37. data/lib/apiwork/adapter/standard/capability/filtering.rb +18 -0
  38. data/lib/apiwork/adapter/standard/capability/including/contract_builder.rb +169 -0
  39. data/lib/apiwork/adapter/standard/capability/including/operation.rb +20 -0
  40. data/lib/apiwork/adapter/standard/capability/including.rb +16 -0
  41. data/lib/apiwork/adapter/standard/capability/pagination/api_builder.rb +34 -0
  42. data/lib/apiwork/adapter/standard/capability/pagination/contract_builder.rb +35 -0
  43. data/lib/apiwork/adapter/standard/capability/pagination/operation/paginate/cursor.rb +84 -0
  44. data/lib/apiwork/adapter/standard/capability/pagination/operation/paginate/offset.rb +66 -0
  45. data/lib/apiwork/adapter/standard/capability/pagination/operation/paginate.rb +24 -0
  46. data/lib/apiwork/adapter/standard/capability/pagination/operation.rb +24 -0
  47. data/lib/apiwork/adapter/standard/capability/pagination.rb +21 -0
  48. data/lib/apiwork/adapter/standard/capability/sorting/api_builder.rb +19 -0
  49. data/lib/apiwork/adapter/standard/capability/sorting/contract_builder.rb +84 -0
  50. data/lib/apiwork/adapter/standard/capability/sorting/operation/sort.rb +83 -0
  51. data/lib/apiwork/adapter/standard/capability/sorting/operation.rb +22 -0
  52. data/lib/apiwork/adapter/standard/capability/sorting.rb +17 -0
  53. data/lib/apiwork/adapter/standard/capability/writing/constants.rb +15 -0
  54. data/lib/apiwork/adapter/standard/capability/writing/contract_builder.rb +253 -0
  55. data/lib/apiwork/adapter/standard/capability/writing/operation/issue_mapper.rb +210 -0
  56. data/lib/apiwork/adapter/standard/capability/writing/operation.rb +32 -0
  57. data/lib/apiwork/adapter/standard/capability/writing/request_transformer.rb +37 -0
  58. data/lib/apiwork/adapter/standard/capability/writing.rb +17 -0
  59. data/lib/apiwork/adapter/standard/includes_resolver.rb +106 -0
  60. data/lib/apiwork/adapter/standard.rb +22 -0
  61. data/lib/apiwork/adapter/wrapper/base.rb +70 -0
  62. data/lib/apiwork/adapter/wrapper/collection/base.rb +60 -0
  63. data/lib/apiwork/adapter/wrapper/collection/default.rb +47 -0
  64. data/lib/apiwork/adapter/wrapper/error/base.rb +30 -0
  65. data/lib/apiwork/adapter/wrapper/error/default.rb +34 -0
  66. data/lib/apiwork/adapter/wrapper/member/base.rb +58 -0
  67. data/lib/apiwork/adapter/wrapper/member/default.rb +40 -0
  68. data/lib/apiwork/adapter/wrapper/shape.rb +203 -0
  69. data/lib/apiwork/adapter.rb +50 -0
  70. data/lib/apiwork/api/base.rb +802 -0
  71. data/lib/apiwork/api/element.rb +110 -0
  72. data/lib/apiwork/api/enum_registry/definition.rb +51 -0
  73. data/lib/apiwork/api/enum_registry.rb +98 -0
  74. data/lib/apiwork/api/info/contact.rb +67 -0
  75. data/lib/apiwork/api/info/license.rb +50 -0
  76. data/lib/apiwork/api/info/server.rb +50 -0
  77. data/lib/apiwork/api/info.rb +221 -0
  78. data/lib/apiwork/api/object.rb +235 -0
  79. data/lib/apiwork/api/registry.rb +33 -0
  80. data/lib/apiwork/api/representation_registry.rb +76 -0
  81. data/lib/apiwork/api/resource/action.rb +41 -0
  82. data/lib/apiwork/api/resource.rb +648 -0
  83. data/lib/apiwork/api/router.rb +104 -0
  84. data/lib/apiwork/api/type_registry/definition.rb +117 -0
  85. data/lib/apiwork/api/type_registry.rb +99 -0
  86. data/lib/apiwork/api/union.rb +49 -0
  87. data/lib/apiwork/api.rb +85 -0
  88. data/lib/apiwork/configurable.rb +71 -0
  89. data/lib/apiwork/configuration/option.rb +125 -0
  90. data/lib/apiwork/configuration/validatable.rb +25 -0
  91. data/lib/apiwork/configuration.rb +95 -0
  92. data/lib/apiwork/configuration_error.rb +6 -0
  93. data/lib/apiwork/constraint_error.rb +20 -0
  94. data/lib/apiwork/contract/action/request.rb +79 -0
  95. data/lib/apiwork/contract/action/response.rb +87 -0
  96. data/lib/apiwork/contract/action.rb +258 -0
  97. data/lib/apiwork/contract/base.rb +714 -0
  98. data/lib/apiwork/contract/element.rb +130 -0
  99. data/lib/apiwork/contract/object/coercer.rb +194 -0
  100. data/lib/apiwork/contract/object/deserializer.rb +101 -0
  101. data/lib/apiwork/contract/object/transformer.rb +95 -0
  102. data/lib/apiwork/contract/object/validator/result.rb +27 -0
  103. data/lib/apiwork/contract/object/validator.rb +734 -0
  104. data/lib/apiwork/contract/object.rb +566 -0
  105. data/lib/apiwork/contract/request_parser/result.rb +25 -0
  106. data/lib/apiwork/contract/request_parser.rb +72 -0
  107. data/lib/apiwork/contract/response_parser/result.rb +25 -0
  108. data/lib/apiwork/contract/response_parser.rb +35 -0
  109. data/lib/apiwork/contract/union.rb +56 -0
  110. data/lib/apiwork/contract_error.rb +9 -0
  111. data/lib/apiwork/controller.rb +300 -0
  112. data/lib/apiwork/domain_error.rb +13 -0
  113. data/lib/apiwork/element.rb +386 -0
  114. data/lib/apiwork/engine.rb +20 -0
  115. data/lib/apiwork/error.rb +6 -0
  116. data/lib/apiwork/error_code/definition.rb +63 -0
  117. data/lib/apiwork/error_code/registry.rb +18 -0
  118. data/lib/apiwork/error_code.rb +132 -0
  119. data/lib/apiwork/export/base.rb +291 -0
  120. data/lib/apiwork/export/open_api.rb +600 -0
  121. data/lib/apiwork/export/pipeline/writer.rb +66 -0
  122. data/lib/apiwork/export/pipeline.rb +84 -0
  123. data/lib/apiwork/export/registry.rb +16 -0
  124. data/lib/apiwork/export/surface_resolver.rb +189 -0
  125. data/lib/apiwork/export/type_analysis.rb +170 -0
  126. data/lib/apiwork/export/type_script.rb +23 -0
  127. data/lib/apiwork/export/type_script_mapper.rb +349 -0
  128. data/lib/apiwork/export/zod.rb +39 -0
  129. data/lib/apiwork/export/zod_mapper.rb +421 -0
  130. data/lib/apiwork/export.rb +80 -0
  131. data/lib/apiwork/http_error.rb +16 -0
  132. data/lib/apiwork/introspection/action/request.rb +66 -0
  133. data/lib/apiwork/introspection/action/response.rb +57 -0
  134. data/lib/apiwork/introspection/action.rb +124 -0
  135. data/lib/apiwork/introspection/api/info/contact.rb +59 -0
  136. data/lib/apiwork/introspection/api/info/license.rb +49 -0
  137. data/lib/apiwork/introspection/api/info/server.rb +50 -0
  138. data/lib/apiwork/introspection/api/info.rb +107 -0
  139. data/lib/apiwork/introspection/api/resource.rb +83 -0
  140. data/lib/apiwork/introspection/api.rb +92 -0
  141. data/lib/apiwork/introspection/contract.rb +63 -0
  142. data/lib/apiwork/introspection/dump/action.rb +101 -0
  143. data/lib/apiwork/introspection/dump/api.rb +119 -0
  144. data/lib/apiwork/introspection/dump/contract.rb +129 -0
  145. data/lib/apiwork/introspection/dump/param.rb +486 -0
  146. data/lib/apiwork/introspection/dump/resource.rb +112 -0
  147. data/lib/apiwork/introspection/dump/type.rb +339 -0
  148. data/lib/apiwork/introspection/dump.rb +17 -0
  149. data/lib/apiwork/introspection/enum.rb +63 -0
  150. data/lib/apiwork/introspection/error_code.rb +44 -0
  151. data/lib/apiwork/introspection/param/array.rb +88 -0
  152. data/lib/apiwork/introspection/param/base.rb +285 -0
  153. data/lib/apiwork/introspection/param/binary.rb +73 -0
  154. data/lib/apiwork/introspection/param/boolean.rb +73 -0
  155. data/lib/apiwork/introspection/param/date.rb +73 -0
  156. data/lib/apiwork/introspection/param/date_time.rb +73 -0
  157. data/lib/apiwork/introspection/param/decimal.rb +121 -0
  158. data/lib/apiwork/introspection/param/integer.rb +131 -0
  159. data/lib/apiwork/introspection/param/literal.rb +45 -0
  160. data/lib/apiwork/introspection/param/number.rb +121 -0
  161. data/lib/apiwork/introspection/param/object.rb +59 -0
  162. data/lib/apiwork/introspection/param/reference.rb +45 -0
  163. data/lib/apiwork/introspection/param/string.rb +122 -0
  164. data/lib/apiwork/introspection/param/time.rb +73 -0
  165. data/lib/apiwork/introspection/param/union.rb +57 -0
  166. data/lib/apiwork/introspection/param/unknown.rb +26 -0
  167. data/lib/apiwork/introspection/param/uuid.rb +73 -0
  168. data/lib/apiwork/introspection/param.rb +31 -0
  169. data/lib/apiwork/introspection/type.rb +129 -0
  170. data/lib/apiwork/introspection.rb +28 -0
  171. data/lib/apiwork/issue.rb +80 -0
  172. data/lib/apiwork/json_pointer.rb +21 -0
  173. data/lib/apiwork/object.rb +1618 -0
  174. data/lib/apiwork/reference_generator.rb +622 -0
  175. data/lib/apiwork/registry.rb +56 -0
  176. data/lib/apiwork/representation/association.rb +391 -0
  177. data/lib/apiwork/representation/attribute.rb +335 -0
  178. data/lib/apiwork/representation/base.rb +819 -0
  179. data/lib/apiwork/representation/deserializer.rb +95 -0
  180. data/lib/apiwork/representation/element.rb +128 -0
  181. data/lib/apiwork/representation/inheritance.rb +78 -0
  182. data/lib/apiwork/representation/model_detector.rb +75 -0
  183. data/lib/apiwork/representation/root_key.rb +35 -0
  184. data/lib/apiwork/representation/serializer.rb +127 -0
  185. data/lib/apiwork/request.rb +79 -0
  186. data/lib/apiwork/response.rb +56 -0
  187. data/lib/apiwork/union.rb +102 -0
  188. data/lib/apiwork/version.rb +2 -2
  189. data/lib/apiwork.rb +61 -3
  190. data/lib/generators/apiwork/api_generator.rb +38 -0
  191. data/lib/generators/apiwork/contract_generator.rb +25 -0
  192. data/lib/generators/apiwork/install_generator.rb +27 -0
  193. data/lib/generators/apiwork/representation_generator.rb +25 -0
  194. data/lib/generators/apiwork/templates/api/api.rb.tt +4 -0
  195. data/lib/generators/apiwork/templates/contract/contract.rb.tt +6 -0
  196. data/lib/generators/apiwork/templates/install/application_contract.rb.tt +5 -0
  197. data/lib/generators/apiwork/templates/install/application_representation.rb.tt +5 -0
  198. data/lib/generators/apiwork/templates/representation/representation.rb.tt +6 -0
  199. data/lib/tasks/apiwork.rake +102 -0
  200. metadata +319 -19
  201. data/.rubocop.yml +0 -8
  202. data/sig/apiwork.rbs +0 -4
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apiwork
4
+ module Introspection
5
+ # @api public
6
+ # Wraps action definitions within a resource.
7
+ #
8
+ # @example
9
+ # resource.actions[:show].method # => :get
10
+ # resource.actions[:show].path # => "/posts/:id"
11
+ # resource.actions[:create].request # => Action::Request
12
+ #
13
+ # resource.actions.each_value do |action|
14
+ # action.method # => :get, :post, :patch, :delete
15
+ # action.request # => Action::Request
16
+ # action.response # => Action::Response
17
+ # action.deprecated? # => false
18
+ # end
19
+ class Action
20
+ def initialize(dump)
21
+ @dump = dump
22
+ end
23
+
24
+ # @api public
25
+ # The path for this action.
26
+ #
27
+ # @return [String]
28
+ def path
29
+ @dump[:path]
30
+ end
31
+
32
+ # @api public
33
+ # The method for this action.
34
+ #
35
+ # @return [Symbol]
36
+ def method
37
+ @dump[:method]
38
+ end
39
+
40
+ # @api public
41
+ # The request for this action.
42
+ #
43
+ # @return [Action::Request]
44
+ def request
45
+ @request ||= Request.new(@dump[:request])
46
+ end
47
+
48
+ # @api public
49
+ # The response for this action.
50
+ #
51
+ # @return [Action::Response]
52
+ def response
53
+ @response ||= Response.new(@dump[:response])
54
+ end
55
+
56
+ # @api public
57
+ # The raises for this action.
58
+ #
59
+ # @return [Array<Symbol>]
60
+ def raises
61
+ @dump[:raises]
62
+ end
63
+
64
+ # @api public
65
+ # The summary for this action.
66
+ #
67
+ # @return [String, nil]
68
+ def summary
69
+ @dump[:summary]
70
+ end
71
+
72
+ # @api public
73
+ # The description for this action.
74
+ #
75
+ # @return [String, nil]
76
+ def description
77
+ @dump[:description]
78
+ end
79
+
80
+ # @api public
81
+ # The tags for this action.
82
+ #
83
+ # @return [Array<String>]
84
+ def tags
85
+ @dump[:tags]
86
+ end
87
+
88
+ # @api public
89
+ # The operation ID for this action.
90
+ #
91
+ # @return [String, nil]
92
+ def operation_id
93
+ @dump[:operation_id]
94
+ end
95
+
96
+ # @api public
97
+ # Whether this action is deprecated.
98
+ #
99
+ # @return [Boolean]
100
+ def deprecated?
101
+ @dump[:deprecated]
102
+ end
103
+
104
+ # @api public
105
+ # Converts this action to a hash.
106
+ #
107
+ # @return [Hash]
108
+ def to_h
109
+ {
110
+ deprecated: deprecated?,
111
+ description: description,
112
+ method: method,
113
+ operation_id: operation_id,
114
+ path: path,
115
+ raises: raises,
116
+ request: request.to_h,
117
+ response: response.to_h,
118
+ summary: summary,
119
+ tags: tags,
120
+ }
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apiwork
4
+ module Introspection
5
+ class API
6
+ class Info
7
+ # @api public
8
+ # Wraps API contact information.
9
+ #
10
+ # @example
11
+ # contact = api.info.contact
12
+ # contact.name # => "API Support"
13
+ # contact.email # => "support@example.com"
14
+ # contact.url # => "https://example.com/support"
15
+ class Contact
16
+ def initialize(dump)
17
+ @dump = dump
18
+ end
19
+
20
+ # @api public
21
+ # The contact name.
22
+ #
23
+ # @return [String, nil]
24
+ def name
25
+ @dump[:name]
26
+ end
27
+
28
+ # @api public
29
+ # The contact email.
30
+ #
31
+ # @return [String, nil]
32
+ def email
33
+ @dump[:email]
34
+ end
35
+
36
+ # @api public
37
+ # The contact URL.
38
+ #
39
+ # @return [String, nil]
40
+ def url
41
+ @dump[:url]
42
+ end
43
+
44
+ # @api public
45
+ # Converts this contact to a hash.
46
+ #
47
+ # @return [Hash]
48
+ def to_h
49
+ {
50
+ email: email,
51
+ name: name,
52
+ url: url,
53
+ }
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apiwork
4
+ module Introspection
5
+ class API
6
+ class Info
7
+ # @api public
8
+ # Wraps API license information.
9
+ #
10
+ # @example
11
+ # license = api.info.license
12
+ # license.name # => "MIT"
13
+ # license.url # => "https://opensource.org/licenses/MIT"
14
+ class License
15
+ def initialize(dump)
16
+ @dump = dump
17
+ end
18
+
19
+ # @api public
20
+ # The license name.
21
+ #
22
+ # @return [String, nil]
23
+ def name
24
+ @dump[:name]
25
+ end
26
+
27
+ # @api public
28
+ # The license URL.
29
+ #
30
+ # @return [String, nil]
31
+ def url
32
+ @dump[:url]
33
+ end
34
+
35
+ # @api public
36
+ # Converts this license to a hash.
37
+ #
38
+ # @return [Hash]
39
+ def to_h
40
+ {
41
+ name: name,
42
+ url: url,
43
+ }
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apiwork
4
+ module Introspection
5
+ class API
6
+ class Info
7
+ # @api public
8
+ # Wraps API server information.
9
+ #
10
+ # @example
11
+ # api.info.servers.each do |server|
12
+ # puts server.url # => "https://api.example.com"
13
+ # puts server.description # => "Production server"
14
+ # end
15
+ class Server
16
+ def initialize(dump)
17
+ @dump = dump
18
+ end
19
+
20
+ # @api public
21
+ # The server URL.
22
+ #
23
+ # @return [String, nil]
24
+ def url
25
+ @dump[:url]
26
+ end
27
+
28
+ # @api public
29
+ # The server description.
30
+ #
31
+ # @return [String, nil]
32
+ def description
33
+ @dump[:description]
34
+ end
35
+
36
+ # @api public
37
+ # Converts this server to a hash.
38
+ #
39
+ # @return [Hash]
40
+ def to_h
41
+ {
42
+ description: description,
43
+ url: url,
44
+ }
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apiwork
4
+ module Introspection
5
+ class API
6
+ # @api public
7
+ # Wraps API metadata/info.
8
+ #
9
+ # @example
10
+ # info = api.info
11
+ # info.title # => "My API"
12
+ # info.version # => "1.0.0"
13
+ # info.description # => "API for managing resources"
14
+ # info.contact&.email # => "support@example.com"
15
+ # info.license&.name # => "MIT"
16
+ class Info
17
+ def initialize(dump)
18
+ @dump = dump
19
+ end
20
+
21
+ # @api public
22
+ # The API title.
23
+ #
24
+ # @return [String, nil]
25
+ def title
26
+ @dump[:title]
27
+ end
28
+
29
+ # @api public
30
+ # The API version.
31
+ #
32
+ # @return [String, nil]
33
+ def version
34
+ @dump[:version]
35
+ end
36
+
37
+ # @api public
38
+ # The API description.
39
+ #
40
+ # @return [String, nil]
41
+ def description
42
+ @dump[:description]
43
+ end
44
+
45
+ # @api public
46
+ # The API summary.
47
+ #
48
+ # @return [String, nil]
49
+ def summary
50
+ @dump[:summary]
51
+ end
52
+
53
+ # @api public
54
+ # The API terms of service.
55
+ #
56
+ # @return [String, nil]
57
+ def terms_of_service
58
+ @dump[:terms_of_service]
59
+ end
60
+
61
+ # @api public
62
+ # The API contact.
63
+ #
64
+ # @return [Info::Contact, nil]
65
+ # @see Info::Contact
66
+ def contact
67
+ @contact ||= @dump[:contact] ? Contact.new(@dump[:contact]) : nil
68
+ end
69
+
70
+ # @api public
71
+ # The API license.
72
+ #
73
+ # @return [Info::License, nil]
74
+ # @see Info::License
75
+ def license
76
+ @license ||= @dump[:license] ? License.new(@dump[:license]) : nil
77
+ end
78
+
79
+ # @api public
80
+ # The API servers.
81
+ #
82
+ # @return [Array<Info::Server>]
83
+ # @see Info::Server
84
+ def servers
85
+ @servers ||= @dump[:servers].map { |server| Server.new(server) }
86
+ end
87
+
88
+ # @api public
89
+ # Converts the API info to a hash.
90
+ #
91
+ # @return [Hash]
92
+ def to_h
93
+ {
94
+ contact: contact&.to_h,
95
+ description: description,
96
+ license: license&.to_h,
97
+ servers: servers.map(&:to_h),
98
+ summary: summary,
99
+ terms_of_service: terms_of_service,
100
+ title: title,
101
+ version: version,
102
+ }
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apiwork
4
+ module Introspection
5
+ class API
6
+ # @api public
7
+ # Wraps resource definitions.
8
+ #
9
+ # @example
10
+ # resource = api.resources[:invoices]
11
+ #
12
+ # resource.identifier # => "invoices"
13
+ # resource.path # => "invoices"
14
+ # resource.parent_identifiers # => []
15
+ # resource.resources # => {} or nested resources
16
+ #
17
+ # resource.actions.each_value do |action|
18
+ # action.request # => Action::Request
19
+ # action.response # => Action::Response
20
+ # end
21
+ class Resource
22
+ def initialize(dump)
23
+ @dump = dump
24
+ end
25
+
26
+ # @api public
27
+ # The identifier for this resource.
28
+ #
29
+ # @return [String]
30
+ def identifier
31
+ @dump[:identifier]
32
+ end
33
+
34
+ # @api public
35
+ # The path for this resource.
36
+ #
37
+ # @return [String]
38
+ def path
39
+ @dump[:path]
40
+ end
41
+
42
+ # @api public
43
+ # The parent identifiers for this resource.
44
+ #
45
+ # @return [Array<String>]
46
+ def parent_identifiers
47
+ @dump[:parent_identifiers]
48
+ end
49
+
50
+ # @api public
51
+ # The actions for this resource.
52
+ #
53
+ # @return [Hash{Symbol => Introspection::Action}]
54
+ # @see Introspection::Action
55
+ def actions
56
+ @actions ||= @dump[:actions].transform_values { |dump| Action.new(dump) }
57
+ end
58
+
59
+ # @api public
60
+ # The nested resources for this resource.
61
+ #
62
+ # @return [Hash{Symbol => Resource}]
63
+ def resources
64
+ @resources ||= @dump[:resources].transform_values { |dump| Resource.new(dump) }
65
+ end
66
+
67
+ # @api public
68
+ # Converts this resource to a hash.
69
+ #
70
+ # @return [Hash]
71
+ def to_h
72
+ {
73
+ actions: actions.transform_values(&:to_h),
74
+ identifier: identifier,
75
+ parent_identifiers: parent_identifiers,
76
+ path: path,
77
+ resources: resources.transform_values(&:to_h),
78
+ }
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apiwork
4
+ module Introspection
5
+ # @api public
6
+ # Facade for introspected API data.
7
+ #
8
+ # Entry point for accessing all API data. Access resources via {#resources},
9
+ # types via {#types}, enums via {#enums}.
10
+ #
11
+ # @example
12
+ # api = Apiwork::API.introspect('/api/v1', locale: :fr)
13
+ #
14
+ # api.info.title # => "Mon API"
15
+ # api.types[:address].description # => "Type d'adresse"
16
+ # api.enums[:status].values # => ["draft", "published"]
17
+ #
18
+ # api.resources.each_value do |resource|
19
+ # resource.actions.each_value do |action|
20
+ # # ...
21
+ # end
22
+ # end
23
+ class API
24
+ def initialize(dump)
25
+ @dump = dump
26
+ end
27
+
28
+ # @api public
29
+ # The base path for this API.
30
+ #
31
+ # @return [String, nil]
32
+ def base_path
33
+ @dump[:base_path]
34
+ end
35
+
36
+ # @api public
37
+ # The info for this API.
38
+ #
39
+ # @return [API::Info, nil]
40
+ def info
41
+ @info ||= @dump[:info] ? Info.new(@dump[:info]) : nil
42
+ end
43
+
44
+ # @api public
45
+ # The resources for this API.
46
+ #
47
+ # @return [Hash{Symbol => API::Resource}]
48
+ def resources
49
+ @resources ||= @dump[:resources].transform_values { |dump| Resource.new(dump) }
50
+ end
51
+
52
+ # @api public
53
+ # The types for this API.
54
+ #
55
+ # @return [Hash{Symbol => Type}]
56
+ def types
57
+ @types ||= @dump[:types].transform_values { |dump| Type.new(dump) }
58
+ end
59
+
60
+ # @api public
61
+ # The enums for this API.
62
+ #
63
+ # @return [Hash{Symbol => Enum}]
64
+ def enums
65
+ @enums ||= @dump[:enums].transform_values { |dump| Enum.new(dump) }
66
+ end
67
+
68
+ # @api public
69
+ # The error codes for this API.
70
+ #
71
+ # @return [Hash{Symbol => ErrorCode}]
72
+ def error_codes
73
+ @error_codes ||= @dump[:error_codes].transform_values { |dump| ErrorCode.new(dump) }
74
+ end
75
+
76
+ # @api public
77
+ # Converts this API to a hash.
78
+ #
79
+ # @return [Hash]
80
+ def to_h
81
+ {
82
+ base_path:,
83
+ enums: enums.transform_values(&:to_h),
84
+ error_codes: error_codes.transform_values(&:to_h),
85
+ info: info&.to_h,
86
+ resources: resources.transform_values(&:to_h),
87
+ types: types.transform_values(&:to_h),
88
+ }
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apiwork
4
+ module Introspection
5
+ # @api public
6
+ # Facade for introspected contract data.
7
+ #
8
+ # Provides access to actions, types, and enums defined on this contract.
9
+ #
10
+ # @example
11
+ # contract = InvoiceContract.introspect(expand: true)
12
+ #
13
+ # contract.actions[:show].response # => Action::Response
14
+ # contract.types[:address].shape # => { street: ..., city: ... }
15
+ # contract.enums[:status].values # => ["draft", "published"]
16
+ #
17
+ # contract.actions.each_value do |action|
18
+ # action.request # => Action::Request
19
+ # action.response # => Action::Response
20
+ # end
21
+ class Contract
22
+ def initialize(dump)
23
+ @dump = dump
24
+ end
25
+
26
+ # @api public
27
+ # The actions for this contract.
28
+ #
29
+ # @return [Hash{Symbol => Introspection::Action}]
30
+ def actions
31
+ @actions ||= @dump[:actions].transform_values { |dump| Action.new(dump) }
32
+ end
33
+
34
+ # @api public
35
+ # The types for this contract.
36
+ #
37
+ # @return [Hash{Symbol => Type}]
38
+ def types
39
+ @types ||= @dump[:types].transform_values { |dump| Type.new(dump) }
40
+ end
41
+
42
+ # @api public
43
+ # The enums for this contract.
44
+ #
45
+ # @return [Hash{Symbol => Enum}]
46
+ def enums
47
+ @enums ||= @dump[:enums].transform_values { |dump| Enum.new(dump) }
48
+ end
49
+
50
+ # @api public
51
+ # Converts this contract to a hash.
52
+ #
53
+ # @return [Hash]
54
+ def to_h
55
+ {
56
+ actions: actions.transform_values(&:to_h),
57
+ enums: enums.transform_values(&:to_h),
58
+ types: types.transform_values(&:to_h),
59
+ }
60
+ end
61
+ end
62
+ end
63
+ end