apiwork 0.0.0.pre → 0.1.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/LICENSE.txt +2 -2
- data/README.md +117 -1
- data/Rakefile +5 -3
- data/app/controllers/apiwork/errors_controller.rb +13 -0
- data/app/controllers/apiwork/exports_controller.rb +22 -0
- data/lib/apiwork/abstractable.rb +26 -0
- data/lib/apiwork/adapter/base.rb +369 -0
- data/lib/apiwork/adapter/builder/api/base.rb +66 -0
- data/lib/apiwork/adapter/builder/contract/base.rb +86 -0
- data/lib/apiwork/adapter/capability/api/base.rb +51 -0
- data/lib/apiwork/adapter/capability/api/scope.rb +64 -0
- data/lib/apiwork/adapter/capability/base.rb +291 -0
- data/lib/apiwork/adapter/capability/contract/base.rb +37 -0
- data/lib/apiwork/adapter/capability/contract/scope.rb +110 -0
- data/lib/apiwork/adapter/capability/operation/base.rb +172 -0
- data/lib/apiwork/adapter/capability/operation/metadata_shape.rb +165 -0
- data/lib/apiwork/adapter/capability/result.rb +21 -0
- data/lib/apiwork/adapter/capability/runner.rb +56 -0
- data/lib/apiwork/adapter/capability/transformer/request/base.rb +72 -0
- data/lib/apiwork/adapter/capability/transformer/response/base.rb +45 -0
- data/lib/apiwork/adapter/registry.rb +16 -0
- data/lib/apiwork/adapter/serializer/error/base.rb +72 -0
- data/lib/apiwork/adapter/serializer/error/default/api_builder.rb +32 -0
- data/lib/apiwork/adapter/serializer/error/default.rb +37 -0
- data/lib/apiwork/adapter/serializer/resource/base.rb +84 -0
- data/lib/apiwork/adapter/serializer/resource/default/contract_builder.rb +209 -0
- data/lib/apiwork/adapter/serializer/resource/default.rb +39 -0
- data/lib/apiwork/adapter/standard/capability/filtering/api_builder.rb +75 -0
- data/lib/apiwork/adapter/standard/capability/filtering/constants.rb +37 -0
- data/lib/apiwork/adapter/standard/capability/filtering/contract_builder.rb +193 -0
- data/lib/apiwork/adapter/standard/capability/filtering/operation/filter/builder.rb +47 -0
- data/lib/apiwork/adapter/standard/capability/filtering/operation/filter/operator_builder.rb +36 -0
- data/lib/apiwork/adapter/standard/capability/filtering/operation/filter.rb +462 -0
- data/lib/apiwork/adapter/standard/capability/filtering/operation.rb +22 -0
- data/lib/apiwork/adapter/standard/capability/filtering/request_transformer.rb +47 -0
- data/lib/apiwork/adapter/standard/capability/filtering.rb +18 -0
- data/lib/apiwork/adapter/standard/capability/including/contract_builder.rb +169 -0
- data/lib/apiwork/adapter/standard/capability/including/operation.rb +20 -0
- data/lib/apiwork/adapter/standard/capability/including.rb +16 -0
- data/lib/apiwork/adapter/standard/capability/pagination/api_builder.rb +34 -0
- data/lib/apiwork/adapter/standard/capability/pagination/contract_builder.rb +35 -0
- data/lib/apiwork/adapter/standard/capability/pagination/operation/paginate/cursor.rb +84 -0
- data/lib/apiwork/adapter/standard/capability/pagination/operation/paginate/offset.rb +66 -0
- data/lib/apiwork/adapter/standard/capability/pagination/operation/paginate.rb +24 -0
- data/lib/apiwork/adapter/standard/capability/pagination/operation.rb +24 -0
- data/lib/apiwork/adapter/standard/capability/pagination.rb +21 -0
- data/lib/apiwork/adapter/standard/capability/sorting/api_builder.rb +19 -0
- data/lib/apiwork/adapter/standard/capability/sorting/contract_builder.rb +84 -0
- data/lib/apiwork/adapter/standard/capability/sorting/operation/sort.rb +83 -0
- data/lib/apiwork/adapter/standard/capability/sorting/operation.rb +22 -0
- data/lib/apiwork/adapter/standard/capability/sorting.rb +17 -0
- data/lib/apiwork/adapter/standard/capability/writing/constants.rb +15 -0
- data/lib/apiwork/adapter/standard/capability/writing/contract_builder.rb +253 -0
- data/lib/apiwork/adapter/standard/capability/writing/operation/issue_mapper.rb +210 -0
- data/lib/apiwork/adapter/standard/capability/writing/operation.rb +32 -0
- data/lib/apiwork/adapter/standard/capability/writing/request_transformer.rb +37 -0
- data/lib/apiwork/adapter/standard/capability/writing.rb +17 -0
- data/lib/apiwork/adapter/standard/includes_resolver.rb +106 -0
- data/lib/apiwork/adapter/standard.rb +22 -0
- data/lib/apiwork/adapter/wrapper/base.rb +70 -0
- data/lib/apiwork/adapter/wrapper/collection/base.rb +60 -0
- data/lib/apiwork/adapter/wrapper/collection/default.rb +47 -0
- data/lib/apiwork/adapter/wrapper/error/base.rb +30 -0
- data/lib/apiwork/adapter/wrapper/error/default.rb +34 -0
- data/lib/apiwork/adapter/wrapper/member/base.rb +58 -0
- data/lib/apiwork/adapter/wrapper/member/default.rb +40 -0
- data/lib/apiwork/adapter/wrapper/shape.rb +203 -0
- data/lib/apiwork/adapter.rb +50 -0
- data/lib/apiwork/api/base.rb +802 -0
- data/lib/apiwork/api/element.rb +110 -0
- data/lib/apiwork/api/enum_registry/definition.rb +51 -0
- data/lib/apiwork/api/enum_registry.rb +98 -0
- data/lib/apiwork/api/info/contact.rb +67 -0
- data/lib/apiwork/api/info/license.rb +50 -0
- data/lib/apiwork/api/info/server.rb +50 -0
- data/lib/apiwork/api/info.rb +221 -0
- data/lib/apiwork/api/object.rb +235 -0
- data/lib/apiwork/api/registry.rb +33 -0
- data/lib/apiwork/api/representation_registry.rb +76 -0
- data/lib/apiwork/api/resource/action.rb +41 -0
- data/lib/apiwork/api/resource.rb +648 -0
- data/lib/apiwork/api/router.rb +104 -0
- data/lib/apiwork/api/type_registry/definition.rb +117 -0
- data/lib/apiwork/api/type_registry.rb +99 -0
- data/lib/apiwork/api/union.rb +49 -0
- data/lib/apiwork/api.rb +85 -0
- data/lib/apiwork/configurable.rb +71 -0
- data/lib/apiwork/configuration/option.rb +125 -0
- data/lib/apiwork/configuration/validatable.rb +25 -0
- data/lib/apiwork/configuration.rb +95 -0
- data/lib/apiwork/configuration_error.rb +6 -0
- data/lib/apiwork/constraint_error.rb +20 -0
- data/lib/apiwork/contract/action/request.rb +79 -0
- data/lib/apiwork/contract/action/response.rb +87 -0
- data/lib/apiwork/contract/action.rb +258 -0
- data/lib/apiwork/contract/base.rb +714 -0
- data/lib/apiwork/contract/element.rb +130 -0
- data/lib/apiwork/contract/object/coercer.rb +194 -0
- data/lib/apiwork/contract/object/deserializer.rb +101 -0
- data/lib/apiwork/contract/object/transformer.rb +95 -0
- data/lib/apiwork/contract/object/validator/result.rb +27 -0
- data/lib/apiwork/contract/object/validator.rb +734 -0
- data/lib/apiwork/contract/object.rb +566 -0
- data/lib/apiwork/contract/request_parser/result.rb +25 -0
- data/lib/apiwork/contract/request_parser.rb +72 -0
- data/lib/apiwork/contract/response_parser/result.rb +25 -0
- data/lib/apiwork/contract/response_parser.rb +35 -0
- data/lib/apiwork/contract/union.rb +56 -0
- data/lib/apiwork/contract_error.rb +9 -0
- data/lib/apiwork/controller.rb +300 -0
- data/lib/apiwork/domain_error.rb +13 -0
- data/lib/apiwork/element.rb +386 -0
- data/lib/apiwork/engine.rb +20 -0
- data/lib/apiwork/error.rb +6 -0
- data/lib/apiwork/error_code/definition.rb +63 -0
- data/lib/apiwork/error_code/registry.rb +18 -0
- data/lib/apiwork/error_code.rb +132 -0
- data/lib/apiwork/export/base.rb +291 -0
- data/lib/apiwork/export/open_api.rb +600 -0
- data/lib/apiwork/export/pipeline/writer.rb +66 -0
- data/lib/apiwork/export/pipeline.rb +84 -0
- data/lib/apiwork/export/registry.rb +16 -0
- data/lib/apiwork/export/surface_resolver.rb +189 -0
- data/lib/apiwork/export/type_analysis.rb +170 -0
- data/lib/apiwork/export/type_script.rb +23 -0
- data/lib/apiwork/export/type_script_mapper.rb +349 -0
- data/lib/apiwork/export/zod.rb +39 -0
- data/lib/apiwork/export/zod_mapper.rb +421 -0
- data/lib/apiwork/export.rb +80 -0
- data/lib/apiwork/http_error.rb +16 -0
- data/lib/apiwork/introspection/action/request.rb +66 -0
- data/lib/apiwork/introspection/action/response.rb +57 -0
- data/lib/apiwork/introspection/action.rb +124 -0
- data/lib/apiwork/introspection/api/info/contact.rb +59 -0
- data/lib/apiwork/introspection/api/info/license.rb +49 -0
- data/lib/apiwork/introspection/api/info/server.rb +50 -0
- data/lib/apiwork/introspection/api/info.rb +107 -0
- data/lib/apiwork/introspection/api/resource.rb +83 -0
- data/lib/apiwork/introspection/api.rb +92 -0
- data/lib/apiwork/introspection/contract.rb +63 -0
- data/lib/apiwork/introspection/dump/action.rb +101 -0
- data/lib/apiwork/introspection/dump/api.rb +119 -0
- data/lib/apiwork/introspection/dump/contract.rb +129 -0
- data/lib/apiwork/introspection/dump/param.rb +486 -0
- data/lib/apiwork/introspection/dump/resource.rb +112 -0
- data/lib/apiwork/introspection/dump/type.rb +339 -0
- data/lib/apiwork/introspection/dump.rb +17 -0
- data/lib/apiwork/introspection/enum.rb +63 -0
- data/lib/apiwork/introspection/error_code.rb +44 -0
- data/lib/apiwork/introspection/param/array.rb +88 -0
- data/lib/apiwork/introspection/param/base.rb +285 -0
- data/lib/apiwork/introspection/param/binary.rb +73 -0
- data/lib/apiwork/introspection/param/boolean.rb +73 -0
- data/lib/apiwork/introspection/param/date.rb +73 -0
- data/lib/apiwork/introspection/param/date_time.rb +73 -0
- data/lib/apiwork/introspection/param/decimal.rb +121 -0
- data/lib/apiwork/introspection/param/integer.rb +131 -0
- data/lib/apiwork/introspection/param/literal.rb +45 -0
- data/lib/apiwork/introspection/param/number.rb +121 -0
- data/lib/apiwork/introspection/param/object.rb +59 -0
- data/lib/apiwork/introspection/param/reference.rb +45 -0
- data/lib/apiwork/introspection/param/string.rb +122 -0
- data/lib/apiwork/introspection/param/time.rb +73 -0
- data/lib/apiwork/introspection/param/union.rb +57 -0
- data/lib/apiwork/introspection/param/unknown.rb +26 -0
- data/lib/apiwork/introspection/param/uuid.rb +73 -0
- data/lib/apiwork/introspection/param.rb +31 -0
- data/lib/apiwork/introspection/type.rb +129 -0
- data/lib/apiwork/introspection.rb +28 -0
- data/lib/apiwork/issue.rb +80 -0
- data/lib/apiwork/json_pointer.rb +21 -0
- data/lib/apiwork/object.rb +1618 -0
- data/lib/apiwork/reference_generator.rb +638 -0
- data/lib/apiwork/registry.rb +56 -0
- data/lib/apiwork/representation/association.rb +391 -0
- data/lib/apiwork/representation/attribute.rb +335 -0
- data/lib/apiwork/representation/base.rb +819 -0
- data/lib/apiwork/representation/deserializer.rb +95 -0
- data/lib/apiwork/representation/element.rb +128 -0
- data/lib/apiwork/representation/inheritance.rb +78 -0
- data/lib/apiwork/representation/model_detector.rb +75 -0
- data/lib/apiwork/representation/root_key.rb +35 -0
- data/lib/apiwork/representation/serializer.rb +127 -0
- data/lib/apiwork/request.rb +79 -0
- data/lib/apiwork/response.rb +56 -0
- data/lib/apiwork/union.rb +102 -0
- data/lib/apiwork/version.rb +2 -2
- data/lib/apiwork.rb +61 -3
- data/lib/generators/apiwork/api_generator.rb +38 -0
- data/lib/generators/apiwork/contract_generator.rb +25 -0
- data/lib/generators/apiwork/install_generator.rb +27 -0
- data/lib/generators/apiwork/representation_generator.rb +25 -0
- data/lib/generators/apiwork/templates/api/api.rb.tt +4 -0
- data/lib/generators/apiwork/templates/contract/contract.rb.tt +6 -0
- data/lib/generators/apiwork/templates/install/application_contract.rb.tt +5 -0
- data/lib/generators/apiwork/templates/install/application_representation.rb.tt +5 -0
- data/lib/generators/apiwork/templates/representation/representation.rb.tt +6 -0
- data/lib/tasks/apiwork.rake +102 -0
- metadata +319 -19
- data/.rubocop.yml +0 -8
- data/sig/apiwork.rbs +0 -4
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Apiwork
|
|
4
|
+
module Introspection
|
|
5
|
+
module Dump
|
|
6
|
+
class Action
|
|
7
|
+
def initialize(contract_action)
|
|
8
|
+
@contract_action = contract_action
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_h
|
|
12
|
+
{
|
|
13
|
+
deprecated: @contract_action.deprecated?,
|
|
14
|
+
description: @contract_action.description || i18n_lookup(:description),
|
|
15
|
+
operation_id: @contract_action.operation_id,
|
|
16
|
+
raises: raises,
|
|
17
|
+
request: build_request(@contract_action.request),
|
|
18
|
+
response: build_response(@contract_action.response),
|
|
19
|
+
summary: @contract_action.summary || i18n_lookup(:summary),
|
|
20
|
+
tags: @contract_action.tags || [],
|
|
21
|
+
}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def i18n_lookup(field)
|
|
27
|
+
contract_class = @contract_action.contract_class
|
|
28
|
+
return nil unless contract_class.name
|
|
29
|
+
|
|
30
|
+
contract_class.api_class.translate(
|
|
31
|
+
:contracts,
|
|
32
|
+
contract_class.name.demodulize.delete_suffix('Contract').underscore,
|
|
33
|
+
:actions,
|
|
34
|
+
@contract_action.name,
|
|
35
|
+
field,
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def build_request(request)
|
|
40
|
+
return { body: {}, query: {} } unless request
|
|
41
|
+
|
|
42
|
+
{
|
|
43
|
+
body: build_param(request.body),
|
|
44
|
+
query: build_param(request.query),
|
|
45
|
+
}
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def build_param(param)
|
|
49
|
+
param ? Param.new(param).to_h : {}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def build_response(response)
|
|
53
|
+
return { body: {}, no_content: false } unless response
|
|
54
|
+
return { body: {}, no_content: true } if response.no_content?
|
|
55
|
+
|
|
56
|
+
body_shape = response.body
|
|
57
|
+
return { body: {}, no_content: false } unless body_shape
|
|
58
|
+
|
|
59
|
+
{ body: Param.new(body_shape, result_wrapper: response.result_wrapper).to_h, no_content: false }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def raises
|
|
63
|
+
(api_level_raises + @contract_action.raises + auto_raises).uniq.sort_by(&:to_s)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def api_level_raises
|
|
67
|
+
api_class = @contract_action.contract_class.api_class
|
|
68
|
+
return [] unless api_class
|
|
69
|
+
|
|
70
|
+
api_class.raises
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def auto_raises
|
|
74
|
+
return [] unless @contract_action.contract_class.representation?
|
|
75
|
+
|
|
76
|
+
action_name = @contract_action.name.to_sym
|
|
77
|
+
return [:unprocessable_entity] if [:create, :update].include?(action_name)
|
|
78
|
+
|
|
79
|
+
return [] if [:index, :show, :destroy].include?(action_name)
|
|
80
|
+
|
|
81
|
+
http_method = find_http_method
|
|
82
|
+
return [] unless http_method
|
|
83
|
+
|
|
84
|
+
[:post, :patch, :put].include?(http_method) ? [:unprocessable_entity] : []
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def find_http_method
|
|
88
|
+
api_class = @contract_action.contract_class.api_class
|
|
89
|
+
return nil unless api_class
|
|
90
|
+
|
|
91
|
+
resource = api_class.root_resource.find_resource do |candidate|
|
|
92
|
+
candidate.contract_class == @contract_action.contract_class
|
|
93
|
+
end
|
|
94
|
+
return nil unless resource
|
|
95
|
+
|
|
96
|
+
resource.actions[@contract_action.name.to_sym]&.method
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Apiwork
|
|
4
|
+
module Introspection
|
|
5
|
+
module Dump
|
|
6
|
+
class API
|
|
7
|
+
def initialize(api_class)
|
|
8
|
+
@api_class = api_class
|
|
9
|
+
@type_dump = Type.new(api_class)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def to_h
|
|
13
|
+
resources = build_resources
|
|
14
|
+
type_dump_hash = @type_dump.to_h
|
|
15
|
+
|
|
16
|
+
{
|
|
17
|
+
resources:,
|
|
18
|
+
base_path: @api_class.transform_path(@api_class.base_path),
|
|
19
|
+
enums: type_dump_hash[:enums],
|
|
20
|
+
error_codes: build_error_codes(collect_all_error_code_keys(resources)),
|
|
21
|
+
info: build_info,
|
|
22
|
+
types: type_dump_hash[:types],
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def collect_all_error_code_keys(resources)
|
|
29
|
+
error_code_keys = Set.new(@api_class.raises)
|
|
30
|
+
|
|
31
|
+
collect_action_error_codes(resources, error_code_keys)
|
|
32
|
+
|
|
33
|
+
error_code_keys.to_a.sort_by(&:to_s)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def collect_action_error_codes(resources, error_code_keys)
|
|
37
|
+
resources.each_value do |resource|
|
|
38
|
+
resource[:actions].each_value do |action|
|
|
39
|
+
error_code_keys.merge(action[:raises] || [])
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
collect_action_error_codes(resource[:resources], error_code_keys) if resource[:resources]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def build_error_codes(error_code_keys)
|
|
47
|
+
error_code_keys.each_with_object({}) do |code, hash|
|
|
48
|
+
error_code = Apiwork::ErrorCode.find!(code)
|
|
49
|
+
hash[code] = {
|
|
50
|
+
description: error_code.description(locale_key: @api_class.locale_key),
|
|
51
|
+
status: error_code.status,
|
|
52
|
+
}
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def build_resources
|
|
57
|
+
@api_class.root_resource.resources.transform_values do |resource|
|
|
58
|
+
Resource.new(resource, @api_class).to_h
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def build_info
|
|
63
|
+
info = @api_class.info
|
|
64
|
+
|
|
65
|
+
title = resolve_info_text(info, :title)
|
|
66
|
+
summary = resolve_info_text(info, :summary)
|
|
67
|
+
description = resolve_info_text(info, :description)
|
|
68
|
+
|
|
69
|
+
return nil unless info || title || summary || description
|
|
70
|
+
|
|
71
|
+
{
|
|
72
|
+
description:,
|
|
73
|
+
summary:,
|
|
74
|
+
title:,
|
|
75
|
+
contact: build_contact(info&.contact),
|
|
76
|
+
deprecated: info ? info.deprecated? : false,
|
|
77
|
+
license: build_license(info&.license),
|
|
78
|
+
servers: build_servers(info ? info.server : []),
|
|
79
|
+
tags: info ? info.tags : [],
|
|
80
|
+
terms_of_service: info&.terms_of_service,
|
|
81
|
+
version: info&.version,
|
|
82
|
+
}
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def resolve_info_text(info, field)
|
|
86
|
+
info&.public_send(field) || @api_class.translate(:info, field)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def build_contact(contact)
|
|
90
|
+
return nil unless contact
|
|
91
|
+
|
|
92
|
+
{
|
|
93
|
+
email: contact.email,
|
|
94
|
+
name: contact.name,
|
|
95
|
+
url: contact.url,
|
|
96
|
+
}
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def build_license(license)
|
|
100
|
+
return nil unless license
|
|
101
|
+
|
|
102
|
+
{
|
|
103
|
+
name: license.name,
|
|
104
|
+
url: license.url,
|
|
105
|
+
}
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def build_servers(servers)
|
|
109
|
+
servers.map do |server|
|
|
110
|
+
{
|
|
111
|
+
description: server.description,
|
|
112
|
+
url: server.url,
|
|
113
|
+
}
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Apiwork
|
|
4
|
+
module Introspection
|
|
5
|
+
module Dump
|
|
6
|
+
class Contract
|
|
7
|
+
def initialize(contract_class, expand: false)
|
|
8
|
+
@contract_class = contract_class
|
|
9
|
+
@expand = expand
|
|
10
|
+
@type_dump = Type.new(contract_class.api_class)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def to_h
|
|
14
|
+
@contract_class.api_class.ensure_all_contracts_built!
|
|
15
|
+
|
|
16
|
+
result = { actions: {} }
|
|
17
|
+
|
|
18
|
+
action_names = available_actions
|
|
19
|
+
action_names = @contract_class.actions.keys if action_names.empty?
|
|
20
|
+
|
|
21
|
+
action_names.each do |action_name|
|
|
22
|
+
contract_action = @contract_class.action_for(action_name)
|
|
23
|
+
result[:actions][action_name] = Action.new(contract_action).to_h if contract_action
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if @expand
|
|
27
|
+
types, enums = build_referenced_types_and_enums(result[:actions])
|
|
28
|
+
else
|
|
29
|
+
types = build_local_types
|
|
30
|
+
enums = build_local_enums
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
result[:types] = types
|
|
34
|
+
result[:enums] = enums
|
|
35
|
+
|
|
36
|
+
result
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def build_local_types
|
|
42
|
+
@contract_class.api_class.type_registry.each_pair
|
|
43
|
+
.select { |_name, type_definition| type_definition.scope == @contract_class }
|
|
44
|
+
.reject { |_, type_definition| type_definition.fragment? }
|
|
45
|
+
.sort_by { |name, _type_definition| name.to_s }
|
|
46
|
+
.each_with_object({}) do |(name, type_definition), result|
|
|
47
|
+
result[name] = @type_dump.build_type(name, type_definition)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def build_local_enums
|
|
52
|
+
@contract_class.api_class.enum_registry.each_pair
|
|
53
|
+
.select { |_name, enum_definition| enum_definition.scope == @contract_class }
|
|
54
|
+
.sort_by { |name, _enum_definition| name.to_s }
|
|
55
|
+
.each_with_object({}) do |(name, enum_definition), result|
|
|
56
|
+
result[name] = @type_dump.build_enum(name, enum_definition)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def build_referenced_types_and_enums(actions_dump)
|
|
61
|
+
type_registry = @contract_class.api_class.type_registry
|
|
62
|
+
enum_registry = @contract_class.api_class.enum_registry
|
|
63
|
+
|
|
64
|
+
referenced_types = Set.new
|
|
65
|
+
referenced_enums = Set.new
|
|
66
|
+
dumped_types = {}
|
|
67
|
+
visited_types = Set.new
|
|
68
|
+
|
|
69
|
+
collect_references(actions_dump, referenced_types, referenced_enums)
|
|
70
|
+
|
|
71
|
+
until (pending_types = referenced_types - visited_types).empty?
|
|
72
|
+
pending_types.each do |type_name|
|
|
73
|
+
visited_types << type_name
|
|
74
|
+
|
|
75
|
+
type_definition = type_registry[type_name]
|
|
76
|
+
next unless type_definition
|
|
77
|
+
|
|
78
|
+
dumped = @type_dump.build_type(type_name, type_definition)
|
|
79
|
+
dumped_types[type_name] = dumped
|
|
80
|
+
|
|
81
|
+
collect_references(dumped, referenced_types, referenced_enums)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
dumped_enums = referenced_enums.each_with_object({}) do |enum_name, result|
|
|
86
|
+
enum_definition = enum_registry[enum_name]
|
|
87
|
+
result[enum_name] = @type_dump.build_enum(enum_name, enum_definition) if enum_definition
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
types = dumped_types.sort_by { |name, _| name.to_s }.to_h
|
|
91
|
+
enums = dumped_enums.sort_by { |name, _| name.to_s }.to_h
|
|
92
|
+
|
|
93
|
+
[types, enums]
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def collect_references(dump, types, enums)
|
|
97
|
+
case dump
|
|
98
|
+
when Hash
|
|
99
|
+
types << dump[:reference].to_sym if dump[:type] == :reference && dump[:reference]
|
|
100
|
+
|
|
101
|
+
types << dump[:of][:reference].to_sym if dump[:of].is_a?(Hash) && dump[:of][:type] == :reference && dump[:of][:reference]
|
|
102
|
+
|
|
103
|
+
enums << dump[:enum] if dump[:enum].is_a?(Symbol)
|
|
104
|
+
|
|
105
|
+
dump.each_value { |value| collect_references(value, types, enums) }
|
|
106
|
+
when Array
|
|
107
|
+
dump.each { |item| collect_references(item, types, enums) }
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def available_actions
|
|
112
|
+
return [] unless resource
|
|
113
|
+
|
|
114
|
+
resource.actions.keys
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def resource
|
|
118
|
+
@contract_class.api_class.root_resource.find_resource(resource_name)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def resource_name
|
|
122
|
+
return nil unless @contract_class.name
|
|
123
|
+
|
|
124
|
+
@contract_class.name.demodulize.delete_suffix('Contract').underscore.pluralize.to_sym
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|