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.
- 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 +622 -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,291 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Apiwork
|
|
4
|
+
module Export
|
|
5
|
+
# @api public
|
|
6
|
+
# Base class for exports.
|
|
7
|
+
#
|
|
8
|
+
# Subclass this to create custom export formats. Declare output type
|
|
9
|
+
# and override `#generate` to produce output.
|
|
10
|
+
#
|
|
11
|
+
# @example Hash export (supports json/yaml)
|
|
12
|
+
# class OpenAPI < Apiwork::Export::Base
|
|
13
|
+
# export_name :openapi
|
|
14
|
+
# output :hash
|
|
15
|
+
#
|
|
16
|
+
# def generate
|
|
17
|
+
# { openapi: '3.1.0', ... } # Returns Hash
|
|
18
|
+
# end
|
|
19
|
+
# end
|
|
20
|
+
#
|
|
21
|
+
# @example String export (fixed format)
|
|
22
|
+
# class ProtobufExport < Apiwork::Export::Base
|
|
23
|
+
# export_name :protobuf
|
|
24
|
+
# output :string
|
|
25
|
+
# file_extension '.proto'
|
|
26
|
+
#
|
|
27
|
+
# def generate
|
|
28
|
+
# "syntax = \"proto3\";\n..." # Returns String
|
|
29
|
+
# end
|
|
30
|
+
# end
|
|
31
|
+
#
|
|
32
|
+
# # Register the export
|
|
33
|
+
# Apiwork::Export.register(ProtobufExport)
|
|
34
|
+
class Base
|
|
35
|
+
include Configurable
|
|
36
|
+
|
|
37
|
+
option :key_format, enum: %i[keep camel pascal kebab underscore], type: :symbol
|
|
38
|
+
option :locale, default: nil, type: :symbol
|
|
39
|
+
|
|
40
|
+
# @!attribute [r] api
|
|
41
|
+
# @api public
|
|
42
|
+
# The API introspection for this export.
|
|
43
|
+
#
|
|
44
|
+
# Primary interface for accessing introspection data in export generators.
|
|
45
|
+
#
|
|
46
|
+
# @return [Introspection::API]
|
|
47
|
+
# @see Introspection::API
|
|
48
|
+
attr_reader :api,
|
|
49
|
+
:api_base_path,
|
|
50
|
+
:options
|
|
51
|
+
|
|
52
|
+
class << self
|
|
53
|
+
# @api public
|
|
54
|
+
# The name for this export.
|
|
55
|
+
#
|
|
56
|
+
# @param name [Symbol, nil] (nil)
|
|
57
|
+
# The export name.
|
|
58
|
+
# @return [Symbol, nil]
|
|
59
|
+
def export_name(name = nil)
|
|
60
|
+
@export_name = name.to_sym if name
|
|
61
|
+
@export_name
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# @api public
|
|
65
|
+
# The output for this export.
|
|
66
|
+
#
|
|
67
|
+
# @param type [Symbol, nil] (nil) [:hash, :string]
|
|
68
|
+
# The output type. :hash for Hash output (json/yaml), :string for String output.
|
|
69
|
+
# @return [Symbol, nil]
|
|
70
|
+
def output(type = nil)
|
|
71
|
+
return @output_type unless type
|
|
72
|
+
|
|
73
|
+
raise ArgumentError, "output must be :hash or :string, got #{type.inspect}" unless %i[hash string].include?(type)
|
|
74
|
+
|
|
75
|
+
@output_type = type
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# @api public
|
|
79
|
+
# The file extension for this export.
|
|
80
|
+
#
|
|
81
|
+
# Only applies to string exports. Hash exports derive extension from format.
|
|
82
|
+
#
|
|
83
|
+
# @param value [String, nil] (nil)
|
|
84
|
+
# The file extension (e.g., '.ts').
|
|
85
|
+
# @return [String, nil]
|
|
86
|
+
def file_extension(value = nil)
|
|
87
|
+
return @file_extension unless value
|
|
88
|
+
|
|
89
|
+
raise ConfigurationError, 'file_extension not allowed for output :hash exports' if output_type == :hash
|
|
90
|
+
|
|
91
|
+
@file_extension = value
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
attr_reader :output_type
|
|
95
|
+
|
|
96
|
+
def generate(api_base_path, format: nil, **options)
|
|
97
|
+
format ||= :json
|
|
98
|
+
|
|
99
|
+
raise ArgumentError, "#{export_name} export does not support #{format} format" if hash_output? && !supports_format?(format)
|
|
100
|
+
|
|
101
|
+
export = new(api_base_path, **options)
|
|
102
|
+
content = export.generate
|
|
103
|
+
export.serialize(content, format:)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def hash_output?
|
|
107
|
+
output_type == :hash
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def string_output?
|
|
111
|
+
output_type == :string
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def supports_format?(format)
|
|
115
|
+
return true if hash_output? && %i[json yaml].include?(format)
|
|
116
|
+
|
|
117
|
+
false
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def file_extension_for(format: nil)
|
|
121
|
+
resolved = format || :json
|
|
122
|
+
|
|
123
|
+
if hash_output?
|
|
124
|
+
resolved == :yaml ? '.yaml' : '.json'
|
|
125
|
+
else
|
|
126
|
+
file_extension
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def content_type_for(format: nil)
|
|
131
|
+
resolved = format || :json
|
|
132
|
+
|
|
133
|
+
if hash_output?
|
|
134
|
+
resolved == :yaml ? 'application/yaml' : 'application/json'
|
|
135
|
+
else
|
|
136
|
+
'text/plain; charset=utf-8'
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def extract_options(source)
|
|
141
|
+
result = {}
|
|
142
|
+
|
|
143
|
+
options.each do |name, option|
|
|
144
|
+
value = source[name] || source[name.to_s]
|
|
145
|
+
next if value.nil?
|
|
146
|
+
|
|
147
|
+
result[name] = if option.nested?
|
|
148
|
+
extract_nested_option(option, value)
|
|
149
|
+
else
|
|
150
|
+
option.cast(value)
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
result
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def extract_nested_option(option, value)
|
|
158
|
+
return nil unless value.is_a?(Hash)
|
|
159
|
+
|
|
160
|
+
nested = {}
|
|
161
|
+
option.children.each do |child_name, child_option|
|
|
162
|
+
child_value = value[child_name] || value[child_name.to_s]
|
|
163
|
+
next if child_value.nil?
|
|
164
|
+
|
|
165
|
+
nested[child_name] = child_option.cast(child_value)
|
|
166
|
+
end
|
|
167
|
+
nested
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def extract_options_from_env
|
|
171
|
+
result = {}
|
|
172
|
+
|
|
173
|
+
options.each do |name, option|
|
|
174
|
+
if option.nested?
|
|
175
|
+
nested = extract_nested_option_from_env(name, option)
|
|
176
|
+
result[name] = nested if nested.any?
|
|
177
|
+
else
|
|
178
|
+
env_key = name.to_s.upcase
|
|
179
|
+
value = ENV[env_key]
|
|
180
|
+
result[name] = option.cast(value) unless value.nil?
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
result
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def extract_nested_option_from_env(parent_name, option)
|
|
188
|
+
nested = {}
|
|
189
|
+
prefix = parent_name.to_s.upcase
|
|
190
|
+
|
|
191
|
+
option.children.each do |child_name, child_option|
|
|
192
|
+
env_key = "#{prefix}_#{child_name.to_s.upcase}"
|
|
193
|
+
value = ENV[env_key]
|
|
194
|
+
next if value.nil?
|
|
195
|
+
|
|
196
|
+
nested[child_name] = child_option.cast(value)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
nested
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def initialize(api_base_path, key_format: nil, locale: nil, **options)
|
|
204
|
+
@api_base_path = api_base_path
|
|
205
|
+
@api_class = API.find!(api_base_path)
|
|
206
|
+
|
|
207
|
+
unless @api_class.export_configs.key?(self.class.export_name)
|
|
208
|
+
raise ConfigurationError,
|
|
209
|
+
"Export :#{self.class.export_name} is not declared for #{api_base_path}. " \
|
|
210
|
+
"Add `export :#{self.class.export_name}` to your API definition."
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
config = @api_class.export_configs[self.class.export_name]
|
|
214
|
+
api_config = extract_options_from_config(config)
|
|
215
|
+
all_options = options.merge(key_format:, locale:).compact
|
|
216
|
+
@options = self.class.default_options.merge(api_config).merge(all_options)
|
|
217
|
+
@options[:key_format] ||= @api_class.key_format || :keep
|
|
218
|
+
validate_options!
|
|
219
|
+
|
|
220
|
+
@api = @api_class.introspect(locale: @options[:locale])
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# @api public
|
|
224
|
+
# Generates the export output.
|
|
225
|
+
#
|
|
226
|
+
# Override this method in subclasses to produce the export format.
|
|
227
|
+
# Access API data via the {#api} method which provides typed access
|
|
228
|
+
# to types, enums, resources, actions, and other introspection data.
|
|
229
|
+
#
|
|
230
|
+
# @return [Hash, String]
|
|
231
|
+
# @see Introspection::API
|
|
232
|
+
def generate
|
|
233
|
+
raise NotImplementedError, "#{self.class} must implement #generate"
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# @api public
|
|
237
|
+
# The key format for this export.
|
|
238
|
+
#
|
|
239
|
+
# @return [Symbol]
|
|
240
|
+
def key_format
|
|
241
|
+
@options[:key_format]
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# @api public
|
|
245
|
+
# Transforms a key according to the configured key format.
|
|
246
|
+
#
|
|
247
|
+
# @param key [String, Symbol]
|
|
248
|
+
# The key to transform.
|
|
249
|
+
# @return [String]
|
|
250
|
+
# @see #key_format
|
|
251
|
+
def transform_key(key)
|
|
252
|
+
key_string = key.to_s
|
|
253
|
+
|
|
254
|
+
return key_string if key_string.match?(/\A[A-Z]+\z/)
|
|
255
|
+
|
|
256
|
+
case key_format
|
|
257
|
+
when :camel then key_string.camelize(:lower)
|
|
258
|
+
when :pascal then key_string.camelize
|
|
259
|
+
when :kebab then key_string.dasherize
|
|
260
|
+
when :underscore then key_string.underscore
|
|
261
|
+
else key_string
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
def extract_options_from_config(config)
|
|
266
|
+
self.class.options.keys.each_with_object({}) do |key, hash|
|
|
267
|
+
value = config.public_send(key)
|
|
268
|
+
hash[key] = value unless value.nil?
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def validate_options!
|
|
273
|
+
@options.each do |name, value|
|
|
274
|
+
option = self.class.options[name]
|
|
275
|
+
option&.validate!(value)
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def serialize(content, format:)
|
|
280
|
+
return content unless content.is_a?(Hash)
|
|
281
|
+
|
|
282
|
+
case format
|
|
283
|
+
when :yaml
|
|
284
|
+
content.deep_stringify_keys.to_yaml
|
|
285
|
+
else
|
|
286
|
+
JSON.pretty_generate(content)
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
end
|