forked from zhandao/zero-rails_openapi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
api.rb
146 lines (114 loc) · 4.99 KB
/
api.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# frozen_string_literal: true
require 'open_api/dsl/helpers'
module OpenApi
module DSL
class Api < Hash
include DSL::Helpers
attr_accessor :action_path, :dry_skip, :dry_only, :dry_blocks, :dryed, :param_order
def initialize(action_path = '', summary: nil, tags: [ ], id: nil)
self.action_path = action_path
self.dry_blocks = [ ]
self.merge!(summary: summary, operationId: id, tags: tags, description: '', parameters: [ ],
requestBody: nil, responses: { }, callbacks: { }, links: { }, security: [ ], servers: [ ])
end
def this_api_is_invalid!(*)
self[:deprecated] = true
end
alias this_api_is_expired! this_api_is_invalid!
alias this_api_is_unused! this_api_is_invalid!
alias this_api_is_under_repair! this_api_is_invalid!
def desc desc
self[:description] = desc
end
alias description desc
def dry only: nil, skip: nil, none: false
return if dry_blocks.blank? || dryed
self.dry_skip = skip && Array(skip)
self.dry_only = none ? [:none] : only && Array(only)
dry_blocks.each { |blk| instance_eval(&blk) }
self.dry_skip = self.dry_only = nil
self.dryed = true
end
def param param_type, name, type, required, schema = { }
return if dry_skip&.include?(name) || dry_only&.exclude?(name)
return unless schema = process_schema_input(type, schema, name)
param_obj = ParamObj.new(name, param_type, type, required, schema)
# The definition of the same name parameter will be overwritten
index = self[:parameters].map(&:name).index(param_obj.name)
index ? self[:parameters][index] = param_obj : self[:parameters] << param_obj
end
alias parameter param
%i[ header header! path path! query query! cookie cookie! ].each do |param_type|
define_method param_type do |name, type = nil, **schema|
param param_type, name, type, (param_type['!'] ? :req : :opt), schema
end
define_method "in_#{param_type}" do |params|
params.each_pair do |param_name, schema|
param param_type, param_name, nil, (param_type['!'] || param_name['!'] ? :req : :opt), schema
end
end
end
def param_ref component_key, *keys
self[:parameters] += [component_key, *keys].map { |key| RefObj.new(:parameter, key) }
end
# options: `exp_params` and `examples`
def request_body required, media_type, data: { }, desc: '', **options
(self[:requestBody] ||= RequestBodyObj.new(required, desc)).absorb(media_type, { data: data , **options })
end
def body_ref component_key
self[:requestBody] = RefObj.new(:requestBody, component_key)
end
%i[ body body! ].each do |method|
define_method method do |media_type, data: { }, **options|
request_body (method['!'] ? :req : :opt), media_type, data: data, **options
end
end
def form data:, **options
body :form, data: data, **options
end
def form! data:, **options
body! :form, data: data, **options
end
def data name, type = nil, schema = { }
schema[:type] = type if type.present?
form data: { name => schema }
end
def response(code, desc, media_type = nil, options)
headers = options[:headers] || {}
data = options[:data] || {}
(self[:responses][code.to_s] ||= ResponseObj.new(desc)).absorb(desc, media_type, headers: headers, data: data, **options)
end
alias_method :resp, :response
alias_method :error, :response
def response_ref code_and_compkey # = { }
code_and_compkey.each { |code, component_key| self[:responses][code.to_s] = RefObj.new(:response, component_key) }
end
def security_require scheme_name, scopes: [ ]
self[:security] << { scheme_name => scopes }
end
alias security security_require
alias auth security_require
alias auth_with security_require
def callback event_name, http_method, callback_url, &block
self[:callbacks].deep_merge! CallbackObj.new(event_name, http_method, callback_url, &block).process
end
def server url, desc: ''
self[:servers] << { url: url, description: desc }
end
def param_examples exp_params = :all, examples_hash
exp_params = self[:parameters].map(&:name) if exp_params == :all
self[:examples] = ExampleObj.new(examples_hash, exp_params, multiple: true).process
end
alias examples param_examples
def run_dsl(dry: false, &block)
instance_exec(&block) if block_given?
dry() if dry
self[:parameters].map!(&:process)
self[:requestBody] = self[:requestBody].try(:process)
self[:responses].each { |code, response| self[:responses][code] = response.process }
self[:responses] = self[:responses].sort.to_h
self.delete_if { |_, v| v.blank? }
end
end
end
end