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,235 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Apiwork
|
|
4
|
+
module API
|
|
5
|
+
# @api public
|
|
6
|
+
# Block context for defining reusable object types.
|
|
7
|
+
#
|
|
8
|
+
# Accessed via `object :name do` in API or contract definitions.
|
|
9
|
+
# Use type methods to define params: {#string}, {#integer}, {#decimal},
|
|
10
|
+
# {#boolean}, {#array}, {#object}, {#union}, {#reference}.
|
|
11
|
+
#
|
|
12
|
+
# @see API::Element Block context for array/variant elements
|
|
13
|
+
# @see Contract::Object Block context for inline objects
|
|
14
|
+
#
|
|
15
|
+
# @example instance_eval style
|
|
16
|
+
# object :item do
|
|
17
|
+
# string :description
|
|
18
|
+
# decimal :amount
|
|
19
|
+
# end
|
|
20
|
+
#
|
|
21
|
+
# @example yield style
|
|
22
|
+
# object :item do |object|
|
|
23
|
+
# object.string :description
|
|
24
|
+
# object.decimal :amount
|
|
25
|
+
# end
|
|
26
|
+
class Object < Apiwork::Object
|
|
27
|
+
# @api public
|
|
28
|
+
# Defines a param with explicit type.
|
|
29
|
+
#
|
|
30
|
+
# This is the verbose form. Prefer sugar methods (string, integer, etc.)
|
|
31
|
+
# for static definitions. Use `param` for dynamic param generation.
|
|
32
|
+
#
|
|
33
|
+
# @param name [Symbol]
|
|
34
|
+
# The param name.
|
|
35
|
+
# @param type [Symbol, nil] (nil) [:array, :binary, :boolean, :date, :datetime, :decimal, :integer, :literal, :number, :object, :string, :time, :union, :uuid]
|
|
36
|
+
# The param type.
|
|
37
|
+
# @param as [Symbol, nil] (nil)
|
|
38
|
+
# The target attribute name.
|
|
39
|
+
# @param default [Object, nil] (nil)
|
|
40
|
+
# The default value.
|
|
41
|
+
# @param deprecated [Boolean] (false)
|
|
42
|
+
# Whether deprecated. Metadata included in exports.
|
|
43
|
+
# @param description [String, nil] (nil)
|
|
44
|
+
# The description. Metadata included in exports.
|
|
45
|
+
# @param discriminator [Symbol, nil] (nil)
|
|
46
|
+
# The discriminator field name. Unions only.
|
|
47
|
+
# @param enum [Array, nil] (nil)
|
|
48
|
+
# The allowed values.
|
|
49
|
+
# @param example [Object, nil] (nil)
|
|
50
|
+
# The example value. Metadata included in exports.
|
|
51
|
+
# @param format [Symbol, nil] (nil) [:date, :datetime, :double, :email, :float, :hostname, :int32, :int64, :ipv4, :ipv6, :password, :url, :uuid]
|
|
52
|
+
# Format hint for exports. Does not change the type, but exports may add validation or documentation based on it.
|
|
53
|
+
# Valid formats by type: `:decimal`/`:number` (`:double`, `:float`), `:integer` (`:int32`, `:int64`),
|
|
54
|
+
# `:string` (`:date`, `:datetime`, `:email`, `:hostname`, `:ipv4`, `:ipv6`, `:password`, `:url`, `:uuid`).
|
|
55
|
+
# @param max [Integer, nil] (nil)
|
|
56
|
+
# The maximum. For `:array`: size. For `:decimal`, `:integer`, `:number`: value. For `:string`: length.
|
|
57
|
+
# @param min [Integer, nil] (nil)
|
|
58
|
+
# The minimum. For `:array`: size. For `:decimal`, `:integer`, `:number`: value. For `:string`: length.
|
|
59
|
+
# @param nullable [Boolean] (false)
|
|
60
|
+
# Whether the value can be `null`.
|
|
61
|
+
# @param of [Symbol, Hash, nil] (nil)
|
|
62
|
+
# The element type. Arrays only.
|
|
63
|
+
# @param optional [Boolean] (false)
|
|
64
|
+
# Whether the param is optional.
|
|
65
|
+
# @param required [Boolean] (false)
|
|
66
|
+
# Whether the param is required.
|
|
67
|
+
# @param shape [API::Object, API::Union, nil] (nil)
|
|
68
|
+
# The pre-built shape.
|
|
69
|
+
# @param value [Object, nil] (nil)
|
|
70
|
+
# The literal value.
|
|
71
|
+
# @yield block for nested structure
|
|
72
|
+
# @yieldparam shape [API::Object, API::Union, API::Element]
|
|
73
|
+
# @return [void]
|
|
74
|
+
#
|
|
75
|
+
# @example Dynamic param generation
|
|
76
|
+
# param_type = :string
|
|
77
|
+
# param :title, type: param_type
|
|
78
|
+
#
|
|
79
|
+
# @example Object with block
|
|
80
|
+
# param :metadata, type: :object do
|
|
81
|
+
# string :key
|
|
82
|
+
# string :value
|
|
83
|
+
# end
|
|
84
|
+
def param(
|
|
85
|
+
name,
|
|
86
|
+
type: nil,
|
|
87
|
+
as: nil,
|
|
88
|
+
default: nil,
|
|
89
|
+
deprecated: false,
|
|
90
|
+
description: nil,
|
|
91
|
+
discriminator: nil,
|
|
92
|
+
enum: nil,
|
|
93
|
+
example: nil,
|
|
94
|
+
format: nil,
|
|
95
|
+
max: nil,
|
|
96
|
+
min: nil,
|
|
97
|
+
nullable: false,
|
|
98
|
+
of: nil,
|
|
99
|
+
optional: false,
|
|
100
|
+
required: false,
|
|
101
|
+
shape: nil,
|
|
102
|
+
value: nil,
|
|
103
|
+
&block
|
|
104
|
+
)
|
|
105
|
+
resolved_of = resolve_of(of, type, &block)
|
|
106
|
+
resolved_shape = type == :array ? nil : (shape || build_shape(type, discriminator, &block))
|
|
107
|
+
discriminator = resolved_of&.discriminator if type == :array
|
|
108
|
+
|
|
109
|
+
param_hash = {
|
|
110
|
+
as:,
|
|
111
|
+
default:,
|
|
112
|
+
deprecated:,
|
|
113
|
+
description:,
|
|
114
|
+
discriminator:,
|
|
115
|
+
enum:,
|
|
116
|
+
example:,
|
|
117
|
+
format:,
|
|
118
|
+
max:,
|
|
119
|
+
min:,
|
|
120
|
+
name:,
|
|
121
|
+
nullable:,
|
|
122
|
+
optional:,
|
|
123
|
+
required:,
|
|
124
|
+
type:,
|
|
125
|
+
value:,
|
|
126
|
+
of: resolved_of,
|
|
127
|
+
}
|
|
128
|
+
param_hash[:shape] = resolved_shape if resolved_shape
|
|
129
|
+
|
|
130
|
+
@params[name] = (@params[name] || {}).merge(param_hash.compact)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# @api public
|
|
134
|
+
# Defines an array param with element type.
|
|
135
|
+
#
|
|
136
|
+
# @param name [Symbol]
|
|
137
|
+
# The param name.
|
|
138
|
+
# @param as [Symbol, nil] (nil)
|
|
139
|
+
# The target attribute name.
|
|
140
|
+
# @param default [Object, nil] (nil)
|
|
141
|
+
# The default value.
|
|
142
|
+
# @param deprecated [Boolean] (false)
|
|
143
|
+
# Whether deprecated. Metadata included in exports.
|
|
144
|
+
# @param description [String, nil] (nil)
|
|
145
|
+
# The description. Metadata included in exports.
|
|
146
|
+
# @param nullable [Boolean] (false)
|
|
147
|
+
# Whether the value can be `null`.
|
|
148
|
+
# @param optional [Boolean] (false)
|
|
149
|
+
# Whether the param is optional.
|
|
150
|
+
# @param required [Boolean] (false)
|
|
151
|
+
# Whether the param is required.
|
|
152
|
+
# @yield block for defining element type
|
|
153
|
+
# @yieldparam element [API::Element]
|
|
154
|
+
# @return [void]
|
|
155
|
+
#
|
|
156
|
+
# @example instance_eval style
|
|
157
|
+
# array :tags do
|
|
158
|
+
# string
|
|
159
|
+
# end
|
|
160
|
+
#
|
|
161
|
+
# @example yield style
|
|
162
|
+
# array :tags do |element|
|
|
163
|
+
# element.string
|
|
164
|
+
# end
|
|
165
|
+
def array(
|
|
166
|
+
name,
|
|
167
|
+
as: nil,
|
|
168
|
+
default: nil,
|
|
169
|
+
deprecated: false,
|
|
170
|
+
description: nil,
|
|
171
|
+
nullable: false,
|
|
172
|
+
optional: false,
|
|
173
|
+
required: false,
|
|
174
|
+
&block
|
|
175
|
+
)
|
|
176
|
+
raise ArgumentError, 'array requires a block' unless block
|
|
177
|
+
|
|
178
|
+
element = Element.new
|
|
179
|
+
block.arity.positive? ? yield(element) : element.instance_eval(&block)
|
|
180
|
+
element.validate!
|
|
181
|
+
|
|
182
|
+
param(
|
|
183
|
+
name,
|
|
184
|
+
as:,
|
|
185
|
+
default:,
|
|
186
|
+
deprecated:,
|
|
187
|
+
description:,
|
|
188
|
+
nullable:,
|
|
189
|
+
optional:,
|
|
190
|
+
required:,
|
|
191
|
+
of: element,
|
|
192
|
+
type: :array,
|
|
193
|
+
)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
private
|
|
197
|
+
|
|
198
|
+
def resolve_of(of, type, &block)
|
|
199
|
+
return nil unless type == :array
|
|
200
|
+
|
|
201
|
+
if block
|
|
202
|
+
element = Element.new
|
|
203
|
+
block.arity.positive? ? yield(element) : element.instance_eval(&block)
|
|
204
|
+
element.validate!
|
|
205
|
+
element
|
|
206
|
+
elsif of.is_a?(Symbol)
|
|
207
|
+
wrap_symbol_in_element(of)
|
|
208
|
+
else
|
|
209
|
+
of
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def wrap_symbol_in_element(type_symbol)
|
|
214
|
+
element = Element.new
|
|
215
|
+
element.of(type_symbol)
|
|
216
|
+
element
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def build_shape(type, discriminator, &block)
|
|
220
|
+
return nil unless block
|
|
221
|
+
|
|
222
|
+
case type
|
|
223
|
+
when :object
|
|
224
|
+
shape = Object.new
|
|
225
|
+
block.arity.positive? ? yield(shape) : shape.instance_eval(&block)
|
|
226
|
+
shape
|
|
227
|
+
when :union
|
|
228
|
+
shape = Union.new(discriminator:)
|
|
229
|
+
block.arity.positive? ? yield(shape) : shape.instance_eval(&block)
|
|
230
|
+
shape
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Apiwork
|
|
4
|
+
module API
|
|
5
|
+
class Registry < Apiwork::Registry
|
|
6
|
+
class << self
|
|
7
|
+
def register(api_class)
|
|
8
|
+
return unless api_class.base_path
|
|
9
|
+
|
|
10
|
+
store[normalize_key(api_class.base_path)] = api_class
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def find(base_path)
|
|
14
|
+
return nil unless base_path
|
|
15
|
+
|
|
16
|
+
super
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def unregister(base_path)
|
|
20
|
+
delete(base_path) if base_path
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def normalize_key(base_path)
|
|
26
|
+
return :root if base_path == '/'
|
|
27
|
+
|
|
28
|
+
base_path.delete_prefix('/').underscore.to_sym
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Apiwork
|
|
4
|
+
module API
|
|
5
|
+
class RepresentationRegistry
|
|
6
|
+
def initialize
|
|
7
|
+
@store = Set.new
|
|
8
|
+
@roles = Hash.new { |hash, key| hash[key] = Set.new }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def register(representation_class)
|
|
12
|
+
@store.add(representation_class)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def mark(representation_class, role)
|
|
16
|
+
@roles[representation_class].add(role)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def nested_writable?(representation_class)
|
|
20
|
+
@roles[representation_class].include?(:nested_writable)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def each(&block)
|
|
24
|
+
@store.each(&block)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def include?(representation_class)
|
|
28
|
+
@store.include?(representation_class)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def clear!
|
|
32
|
+
@store.clear
|
|
33
|
+
@roles.clear
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def filter_types
|
|
37
|
+
@filter_types ||= extract_filter_types(nullable: false)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def nullable_filter_types
|
|
41
|
+
@nullable_filter_types ||= extract_filter_types(nullable: true)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def sortable?
|
|
45
|
+
return @sortable if defined?(@sortable)
|
|
46
|
+
|
|
47
|
+
@sortable = @store.any? do |representation|
|
|
48
|
+
representation.attributes.values.any?(&:sortable?) ||
|
|
49
|
+
representation.associations.values.any?(&:sortable?)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def filterable?
|
|
54
|
+
filter_types.any?
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def options_for(option, key = nil)
|
|
58
|
+
@store.filter_map { |representation| representation.adapter_config.dig(option, key) }.to_set
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def extract_filter_types(nullable:)
|
|
64
|
+
filterable_attributes = @store
|
|
65
|
+
.flat_map { |representation| representation.attributes.values }
|
|
66
|
+
.select(&:filterable?)
|
|
67
|
+
|
|
68
|
+
if nullable
|
|
69
|
+
filterable_attributes.select(&:nullable?).map(&:type).to_set.to_a
|
|
70
|
+
else
|
|
71
|
+
filterable_attributes.map(&:type).to_set.to_a
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Apiwork
|
|
4
|
+
module API
|
|
5
|
+
class Resource
|
|
6
|
+
class Action
|
|
7
|
+
CRUD = %i[index show create update destroy].freeze
|
|
8
|
+
|
|
9
|
+
METHODS = {
|
|
10
|
+
create: :post,
|
|
11
|
+
destroy: :delete,
|
|
12
|
+
index: :get,
|
|
13
|
+
show: :get,
|
|
14
|
+
update: :patch,
|
|
15
|
+
}.freeze
|
|
16
|
+
|
|
17
|
+
attr_reader :method,
|
|
18
|
+
:name,
|
|
19
|
+
:type
|
|
20
|
+
|
|
21
|
+
def initialize(name, method: nil, type: nil)
|
|
22
|
+
@name = name.to_sym
|
|
23
|
+
@type = type || (name == :index ? :collection : :member)
|
|
24
|
+
@method = method || METHODS[name] || :get
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def member?
|
|
28
|
+
type == :member
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def collection?
|
|
32
|
+
type == :collection
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def crud?
|
|
36
|
+
CRUD.include?(name)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|