joshua 0.2.4 → 0.2.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.version +1 -1
- data/lib/doc/doc.rb +25 -27
- data/lib/doc/{special.rb → postman_schema.rb} +27 -26
- data/lib/joshua/base_class.rb +52 -17
- data/lib/joshua/base_instance.rb +24 -10
- data/lib/joshua/response.rb +13 -4
- data/lib/joshua.rb +4 -20
- metadata +4 -33
- data/lib/.DS_Store +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b4b55be6527e985a667ab6ae564cca2ecef5ded3e48dfa951eeee31a1c13b9f
|
4
|
+
data.tar.gz: b5c1dab428666a5d34f2a12ef31a01e934e9e229f11754fffab2d2d74cf26119
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 024c5b93c567fc38985b02a77b4f666e4012c833ee396e7484fe9ad47b66c4a80ef2a988fcc4abb8186c72d5df3363d4c436083d023f75c272e6ef29711381b7
|
7
|
+
data.tar.gz: 6b131eb846f72f571def2ddb2bd566f81581809333f086d8adae7884f6fa505cffe6c49b6ab474fa370dc2e619517fad0de2487f1d8ef063953c330caa3eb283
|
data/.version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.7
|
data/lib/doc/doc.rb
CHANGED
@@ -2,7 +2,9 @@ class Joshua
|
|
2
2
|
module Doc
|
3
3
|
extend self
|
4
4
|
|
5
|
-
|
5
|
+
HtmlTag self
|
6
|
+
|
7
|
+
ICONS ||= {
|
6
8
|
github: {
|
7
9
|
url: 'https://github.com/dux/joshua',
|
8
10
|
image: '<path d="M11.999 1.271C5.925 1.271 1 6.196 1 12.273c0 4.859 3.152 8.982 7.523 10.437.55.1.751-.239.751-.53l-.015-1.872c-3.06.666-3.706-1.474-3.706-1.474-.5-1.271-1.221-1.609-1.221-1.609-.999-.683.075-.668.075-.668 1.105.077 1.685 1.133 1.685 1.133.981 1.681 2.575 1.196 3.202.914.1-.711.384-1.196.698-1.471-2.442-.277-5.011-1.221-5.011-5.436 0-1.201.429-2.183 1.133-2.952-.114-.278-.491-1.397.108-2.911 0 0 .923-.296 3.025 1.127A10.56 10.56 0 0 1 12 6.591c.935.004 1.876.127 2.754.37 2.1-1.423 3.022-1.127 3.022-1.127.6 1.514.223 2.633.11 2.911.705.769 1.131 1.751 1.131 2.952 0 4.225-2.573 5.155-5.023 5.427.395.34.747 1.011.747 2.038 0 1.471-.014 2.657-.014 3.018 0 .293.199.636.756.528C19.851 21.251 23 17.13 23 12.273c0-6.077-4.926-11.002-11.001-11.002z"></path>',
|
@@ -21,10 +23,6 @@ class Joshua
|
|
21
23
|
}
|
22
24
|
}
|
23
25
|
|
24
|
-
def tag
|
25
|
-
HtmlTagBuilder
|
26
|
-
end
|
27
|
-
|
28
26
|
def misc_file name
|
29
27
|
File.read [__dir__, '../misc/%s' % name].join('/')
|
30
28
|
end
|
@@ -34,15 +32,15 @@ class Joshua
|
|
34
32
|
mount_on ||= request.url.split('?').first+'/'
|
35
33
|
mount_on.sub! %r{//$}, '/'
|
36
34
|
|
37
|
-
|
38
|
-
n.head
|
35
|
+
HtmlTag.html do |n|
|
36
|
+
n.tag(:head) do |n|
|
39
37
|
n.title 'Joshua Tester'
|
40
38
|
n.link({ href: "https://fonts.googleapis.com/css?family=Inter:300,400,500,600,700,800,900&display=swap", rel:"stylesheet" })
|
41
39
|
n.link({ rel:"stylesheet", href:"https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" })
|
42
40
|
n.script({ src: 'https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js' })
|
43
41
|
n.script %[window.api_opts = { mount_on: '#{mount_on}', bearer: '#{bearer}' }]
|
44
42
|
end
|
45
|
-
n.body do |n|
|
43
|
+
n.tag(:body) do |n|
|
46
44
|
n.style { misc_file('doc.css') }
|
47
45
|
n.header({ style: 'border-bottom: 1px solid rgb(228, 228, 228);'}) do |n|
|
48
46
|
n._container do |n|
|
@@ -52,7 +50,7 @@ class Joshua
|
|
52
50
|
end
|
53
51
|
end
|
54
52
|
|
55
|
-
n.img src:"https://
|
53
|
+
n.img src:"https://camo.githubusercontent.com/4b5b5447d6af920f58a030740bc8e9cf52dc490a8a560492c6ad3a5c6a0ad076/68747470733a2f2f692e696d6775722e636f6d2f48576f557a356b2e706e67", style: 'width: 40px; z-index: 1; position: absolute; top: 10px; left: 50%;', onclick: "window.open('https://github.com/dux/joshua')"
|
56
54
|
|
57
55
|
n.push modal_dialog
|
58
56
|
|
@@ -77,8 +75,8 @@ class Joshua
|
|
77
75
|
|
78
76
|
n.p '<b>API LIBRARIES</b>'
|
79
77
|
n.div do |n|
|
80
|
-
n.push %[<a class="badge badge-light" href="https://github.com/dux/joshua/
|
81
|
-
n.push %[<a class="badge badge-light" href="https://github.com/dux/joshua/
|
78
|
+
n.push %[<a class="badge badge-light" href="https://github.com/dux/joshua/tree/master/client/ruby" target="capi_ruby">Ruby</a>]
|
79
|
+
n.push %[<a class="badge badge-light" href="https://github.com/dux/joshua/tree/master/client/javascript" target="capi_js">Javascript</a>]
|
82
80
|
n.push %[<a class="badge badge-light" href="#">Python</a>]
|
83
81
|
n.push %[<a class="badge badge-light" href="#">C#</a>]
|
84
82
|
end
|
@@ -114,17 +112,17 @@ class Joshua
|
|
114
112
|
|
115
113
|
# top side navigation icons
|
116
114
|
def top_icons
|
117
|
-
tag.div
|
115
|
+
tag.div style: 'float: right; margin-top: 18px;' do
|
118
116
|
for icon in ICONS.values
|
119
117
|
next unless icon[:url]
|
120
|
-
|
118
|
+
a icon(icon[:image]), target: '_new', href: icon[:url]
|
121
119
|
end
|
122
120
|
end
|
123
121
|
end
|
124
122
|
|
125
123
|
# left side navigation
|
126
124
|
def left_nav
|
127
|
-
|
125
|
+
HtmlTag.div do |n|
|
128
126
|
Joshua.documented.each do |name|
|
129
127
|
n.a({ class:'btn btn-outline-info btn-sm', style: '-font-size: 14px; margin-bottom: 10px;', href: '#%s' % name}) do |n|
|
130
128
|
icon = name.opts.dig(:opts, :icon)
|
@@ -139,7 +137,7 @@ class Joshua
|
|
139
137
|
|
140
138
|
# render doc for all documented classes
|
141
139
|
def index
|
142
|
-
|
140
|
+
HtmlTag.div do |n|
|
143
141
|
for @klass in Joshua.documented
|
144
142
|
@opts = @klass.opts
|
145
143
|
icon = @opts.dig(:opts, :icon)
|
@@ -172,7 +170,7 @@ class Joshua
|
|
172
170
|
def render_type name
|
173
171
|
base = @opts[name] || return
|
174
172
|
|
175
|
-
|
173
|
+
HtmlTag.div do |n|
|
176
174
|
n.br
|
177
175
|
n.h5 '<gray>%s methods</gray>' % name
|
178
176
|
|
@@ -186,23 +184,16 @@ class Joshua
|
|
186
184
|
|
187
185
|
# render api method
|
188
186
|
def render_method name:, m_name:, opts:
|
189
|
-
|
187
|
+
HtmlTag._box do |n|
|
190
188
|
# n.push %[<button onclick="" class="btn btn-info btn-sm request">request</button>]
|
191
189
|
anchor = [@klass, m_name].join('-')
|
192
190
|
|
193
191
|
n.push name_link anchor
|
194
|
-
n.h5 do |n|
|
192
|
+
n.h5 style: 'margin-bottom: 20px;' do |n|
|
195
193
|
n.push "<a href='##{anchor}'>#{m_name}</a>"
|
196
194
|
n.push ' <gray> — %s</gray>' % opts[:desc] if opts[:desc]
|
197
195
|
end
|
198
196
|
|
199
|
-
n.p({style: 'margin: 20px 0 25px 0;'}) do |n|
|
200
|
-
path = @klass.api_path
|
201
|
-
path += '/:id' if name == :member
|
202
|
-
path += "/#{m_name}"
|
203
|
-
n.push %[<button href="#{path}" class="btn btn-outline-info btn-sm" onclick="ModalForm.render(api_opts.mount_on+this.innerHTML, #{(opts[:params] || {}).to_json.gsub('"', '"')})">#{path}</button>]
|
204
|
-
end
|
205
|
-
|
206
197
|
if opts[:detail]
|
207
198
|
n.h6 'Details'
|
208
199
|
n.pre opts[:detail]
|
@@ -224,11 +215,18 @@ class Joshua
|
|
224
215
|
end
|
225
216
|
end
|
226
217
|
end
|
218
|
+
|
219
|
+
n.p style: 'margin: 30px 0 10px 0;' do |n|
|
220
|
+
path = @klass.api_path
|
221
|
+
path += '/:id' if name == :member
|
222
|
+
path += "/#{m_name}"
|
223
|
+
n.push %[<button href="#{path}" class="btn btn-outline-info btn-sm" onclick="ModalForm.render(api_opts.mount_on+this.innerHTML, #{(opts[:params] || {}).to_json.gsub('"', '"')})">#{path}</button>]
|
224
|
+
end
|
227
225
|
end
|
228
226
|
end
|
229
227
|
|
230
228
|
def list_errors
|
231
|
-
|
229
|
+
HtmlTag.div do |n|
|
232
230
|
n.push name_link :api_errors
|
233
231
|
n.push icon ICONS[:error][:image], style: 'position: absolute; margin-left: -40px; margin-top: 1px; fill: #777;'
|
234
232
|
n.h4 { 'Named errors' }
|
@@ -273,4 +271,4 @@ class Joshua
|
|
273
271
|
]
|
274
272
|
end
|
275
273
|
end
|
276
|
-
end
|
274
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# reponse from /api/_/foo
|
2
2
|
|
3
3
|
class Joshua
|
4
|
-
class
|
4
|
+
class PostmanSchema
|
5
5
|
def initialize api
|
6
6
|
@api = api
|
7
7
|
end
|
@@ -17,10 +17,9 @@ class Joshua
|
|
17
17
|
item: []
|
18
18
|
}
|
19
19
|
|
20
|
-
for
|
21
|
-
raw_data = raw[table.to_s]
|
20
|
+
for api_name, raw_data in raw
|
22
21
|
hash = {}
|
23
|
-
hash[:name] =
|
22
|
+
hash[:name] = api_name
|
24
23
|
hash[:item] = []
|
25
24
|
|
26
25
|
for type in [:collection, :member]
|
@@ -30,14 +29,17 @@ class Joshua
|
|
30
29
|
items = []
|
31
30
|
|
32
31
|
for key, value in raw_data[type]
|
33
|
-
items.push postman_add_method(
|
32
|
+
items.push postman_add_method(
|
33
|
+
type: type,
|
34
|
+
object_name: api_name,
|
35
|
+
name: key,
|
36
|
+
item: value
|
37
|
+
)
|
34
38
|
end
|
35
39
|
|
36
40
|
hash[:item].push *items
|
37
|
-
#
|
38
|
-
#
|
39
|
-
# item: items
|
40
|
-
# })
|
41
|
+
# to have it grouped by collection or member methods
|
42
|
+
# hash[:item].push(name: type, item: items)
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
@@ -69,7 +71,7 @@ class Joshua
|
|
69
71
|
|
70
72
|
private
|
71
73
|
|
72
|
-
def postman_add_method type
|
74
|
+
def postman_add_method type:, object_name:, name:, item:
|
73
75
|
path = []
|
74
76
|
|
75
77
|
base = request.url.split('/_/').first
|
@@ -78,24 +80,24 @@ class Joshua
|
|
78
80
|
path.push base.pop
|
79
81
|
base = base.join('/')
|
80
82
|
|
81
|
-
path.push
|
83
|
+
path.push object_name
|
82
84
|
path.push ':id' if type == :member
|
83
85
|
path.push name
|
84
86
|
|
85
87
|
name = '%s*' % name if type == :collection
|
86
88
|
|
87
|
-
out = {
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
89
|
+
out = {}
|
90
|
+
out[:name] = name
|
91
|
+
out[:description] = item[:desc] if item[:desc]
|
92
|
+
out[:request] = {
|
93
|
+
method: item[:allow] || 'POST',
|
94
|
+
header: [],
|
95
|
+
url: {
|
96
|
+
raw: ([base] + path).join('/'),
|
97
|
+
protocol: base.split(':').first,
|
98
|
+
host: request.host.split('.'),
|
99
|
+
port: request.port,
|
100
|
+
path: path
|
99
101
|
}
|
100
102
|
}
|
101
103
|
|
@@ -106,9 +108,8 @@ class Joshua
|
|
106
108
|
|
107
109
|
# if value[:type] == 'model' and key == 'user' you can define "formdata_model"
|
108
110
|
# that returns list of fields for defined model
|
109
|
-
formdata_value =
|
110
|
-
|
111
|
-
opts = { key: key, value: value, name: name, type: type, group: table }
|
111
|
+
formdata_value = if respond_to?(formdata_custom)
|
112
|
+
opts = { key: key, value: value, name: name, type: type, group: object_name }
|
112
113
|
[send(formdata_custom, opts.to_hwia)].flatten
|
113
114
|
else
|
114
115
|
{ key: key, description: value[:type] }
|
data/lib/joshua/base_class.rb
CHANGED
@@ -4,7 +4,9 @@ class Joshua
|
|
4
4
|
|
5
5
|
class << self
|
6
6
|
# perform auto_mount from a rake call
|
7
|
-
def call env
|
7
|
+
def call env = nil
|
8
|
+
return render unless env
|
9
|
+
|
8
10
|
request = Rack::Request.new env
|
9
11
|
|
10
12
|
if request.path == '/favicon.ico'
|
@@ -102,18 +104,19 @@ class Joshua
|
|
102
104
|
end
|
103
105
|
|
104
106
|
# renders api doc or calls api class + action
|
105
|
-
def render action=nil, opts={}
|
107
|
+
def render action = nil, opts = {}
|
106
108
|
if action
|
107
|
-
|
109
|
+
unless action[0]
|
110
|
+
return error 'Action not defined'
|
111
|
+
end
|
108
112
|
else
|
109
113
|
return RenderProxy.new self
|
110
114
|
end
|
111
115
|
|
112
|
-
api_class =
|
113
|
-
if klass = opts.delete(:class)
|
116
|
+
api_class = if klass = opts.delete(:class)
|
114
117
|
# /api/_/foo
|
115
118
|
if klass == '_'
|
116
|
-
klass = Joshua::
|
119
|
+
klass = Joshua::PostmanSchema.new(opts)
|
117
120
|
|
118
121
|
if klass.respond_to?(action.first)
|
119
122
|
return klass.send action.first.to_sym
|
@@ -124,9 +127,10 @@ class Joshua
|
|
124
127
|
|
125
128
|
klass = klass.split('/') if klass.is_a?(String)
|
126
129
|
klass[klass.length-1] += '_api'
|
130
|
+
klass = klass.join('/').classify
|
127
131
|
|
128
132
|
begin
|
129
|
-
klass.
|
133
|
+
klass.constantize
|
130
134
|
rescue NameError => e
|
131
135
|
return error 'API class "%s" not found' % klass
|
132
136
|
end
|
@@ -141,6 +145,11 @@ class Joshua
|
|
141
145
|
Response.auto_format error
|
142
146
|
end
|
143
147
|
|
148
|
+
def render_data action, opts = {}
|
149
|
+
response = render action, params: opts
|
150
|
+
response && (response[:data] || [])
|
151
|
+
end
|
152
|
+
|
144
153
|
# rescue_from CustomError do ...
|
145
154
|
# for unhandled
|
146
155
|
# rescue_from :all do
|
@@ -175,7 +184,7 @@ class Joshua
|
|
175
184
|
|
176
185
|
def error_print error
|
177
186
|
puts
|
178
|
-
puts 'Joshua error dump'
|
187
|
+
puts 'Joshua error dump'
|
179
188
|
puts '---'
|
180
189
|
puts '%s: %s' % [error.class, error.message]
|
181
190
|
puts '---'
|
@@ -192,9 +201,9 @@ class Joshua
|
|
192
201
|
# if you want to make API DOC public use "documented"
|
193
202
|
def documented
|
194
203
|
if self == Joshua
|
195
|
-
DOCUMENTED.
|
204
|
+
DOCUMENTED.sort.uniq.map(&:constantize)
|
196
205
|
else
|
197
|
-
DOCUMENTED.push
|
206
|
+
DOCUMENTED.push to_s unless DOCUMENTED.include?(to_s)
|
198
207
|
end
|
199
208
|
end
|
200
209
|
|
@@ -295,21 +304,37 @@ class Joshua
|
|
295
304
|
end
|
296
305
|
end
|
297
306
|
|
307
|
+
# allow alternative method access
|
308
|
+
# allow :get
|
309
|
+
# if defined, access will be allowed via POST + allowed method
|
298
310
|
def allow type
|
299
311
|
if @method_type
|
300
|
-
|
312
|
+
type = type.to_s.to_sym
|
313
|
+
|
314
|
+
unless %i(get head post put patch delete trace).include?(type)
|
315
|
+
raise ArgumentError.new('"%s" is not allowed http method type' % type)
|
316
|
+
end
|
317
|
+
|
318
|
+
@@opts[:allow] = type.to_s.upcase
|
301
319
|
else
|
302
320
|
raise ArgumentError.new('allow can only be set on methods')
|
303
321
|
end
|
304
322
|
end
|
305
323
|
|
306
|
-
#
|
307
|
-
def
|
308
|
-
if
|
309
|
-
|
310
|
-
|
311
|
-
|
324
|
+
# define response content type (defaults to JSON)
|
325
|
+
def content_type name
|
326
|
+
if name.is_class == Symbol
|
327
|
+
name = case name
|
328
|
+
when :json
|
329
|
+
'application/json'
|
330
|
+
when :text
|
331
|
+
'text/plain'
|
332
|
+
else
|
333
|
+
raise ArgumentError.new('content-type "%s" is not recognized')
|
334
|
+
end
|
312
335
|
end
|
336
|
+
|
337
|
+
@@opts[:content_type] = name
|
313
338
|
end
|
314
339
|
|
315
340
|
# allow methods without @api.bearer token set
|
@@ -390,6 +415,16 @@ class Joshua
|
|
390
415
|
remove_method name
|
391
416
|
end
|
392
417
|
|
418
|
+
def make_hash_html_safe hash
|
419
|
+
(hash || {}).each do |k, v|
|
420
|
+
if v.is_a?(Hash)
|
421
|
+
make_hash_html_safe v
|
422
|
+
elsif v.class == String
|
423
|
+
hash[k] = v.gsub('<', '#LT;')
|
424
|
+
end
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
393
428
|
private
|
394
429
|
|
395
430
|
def only_in_api_methods!
|
data/lib/joshua/base_instance.rb
CHANGED
@@ -24,7 +24,7 @@ class Joshua
|
|
24
24
|
|
25
25
|
attr_reader :api
|
26
26
|
|
27
|
-
def initialize action, params: {}, opts: {}, development: false, id: nil, bearer: nil, api_host: nil
|
27
|
+
def initialize action, params: {}, opts: {}, development: false, id: nil, bearer: nil, api_host: nil, html_safe: true
|
28
28
|
@api = INSTANCE.new
|
29
29
|
|
30
30
|
if action.is_a?(Array)
|
@@ -34,6 +34,10 @@ class Joshua
|
|
34
34
|
@api.action = action
|
35
35
|
end
|
36
36
|
|
37
|
+
if html_safe
|
38
|
+
params = Joshua.make_hash_html_safe params
|
39
|
+
end
|
40
|
+
|
37
41
|
@api.bearer = bearer
|
38
42
|
@api.id ||= id
|
39
43
|
@api.action = @api.action.to_sym
|
@@ -47,9 +51,11 @@ class Joshua
|
|
47
51
|
end
|
48
52
|
|
49
53
|
def execute_call
|
50
|
-
|
51
|
-
|
52
|
-
|
54
|
+
allow_type = @api.method_opts[:allow] || 'POST'
|
55
|
+
request_type = @api.request&.request_method || 'POST'
|
56
|
+
is_allowed = @api.development || ['POST', allow_type].include?(request_type)
|
57
|
+
|
58
|
+
if is_allowed
|
53
59
|
begin
|
54
60
|
parse_api_params
|
55
61
|
parse_annotations unless response.error?
|
@@ -72,6 +78,8 @@ class Joshua
|
|
72
78
|
|
73
79
|
# we execute generic after block in case of error or no
|
74
80
|
execute_callback :after_all
|
81
|
+
else
|
82
|
+
response.error '%s request is not allowed' % request_type
|
75
83
|
end
|
76
84
|
|
77
85
|
@api.raw || response.render
|
@@ -100,18 +108,21 @@ class Joshua
|
|
100
108
|
end
|
101
109
|
|
102
110
|
def resolve_api_body &block
|
111
|
+
# if we have model defiend, we execute member otherwise collection
|
112
|
+
type = @api.id ? :member : :collection
|
113
|
+
api_method = '_api_%s_%s' % [type, @api.action]
|
114
|
+
|
115
|
+
unless respond_to?(api_method)
|
116
|
+
raise Joshua::Error, "Api method #{type}:#{@api.action} not found"
|
117
|
+
end
|
118
|
+
|
103
119
|
# execute before "in the wild"
|
104
120
|
# model @api.pbject should be set here
|
105
121
|
execute_callback :before_all
|
106
122
|
|
107
123
|
instance_exec &block if block
|
108
124
|
|
109
|
-
# if we have model defiend, we execute member otherwise collection
|
110
|
-
type = @api.id ? :member : :collection
|
111
|
-
|
112
125
|
execute_callback 'before_%s' % type
|
113
|
-
api_method = '_api_%s_%s' % [type, @api.action]
|
114
|
-
raise Joshua::Error, "Api method #{type}:#{@api.action} not found" unless respond_to?(api_method)
|
115
126
|
|
116
127
|
data = send api_method
|
117
128
|
response.data data unless response.data?
|
@@ -156,7 +167,9 @@ class Joshua
|
|
156
167
|
|
157
168
|
# inline error raise
|
158
169
|
def error text, args={}
|
159
|
-
|
170
|
+
if @api.development
|
171
|
+
puts 'JOSHUA API Error: %s (%s)' % [text, caller[0]]
|
172
|
+
end
|
160
173
|
|
161
174
|
if err = RESCUE_FROM[text]
|
162
175
|
if err.is_a?(Proc)
|
@@ -166,6 +179,7 @@ class Joshua
|
|
166
179
|
response.error err, args
|
167
180
|
end
|
168
181
|
else
|
182
|
+
rr text
|
169
183
|
response.error text, args
|
170
184
|
end
|
171
185
|
|
data/lib/joshua/response.rb
CHANGED
@@ -39,6 +39,8 @@ class Joshua
|
|
39
39
|
else
|
40
40
|
@message ||= value
|
41
41
|
end
|
42
|
+
|
43
|
+
nil
|
42
44
|
end
|
43
45
|
|
44
46
|
# api meta response, any data is allowed
|
@@ -51,7 +53,7 @@ class Joshua
|
|
51
53
|
end
|
52
54
|
|
53
55
|
# add api response error
|
54
|
-
def error
|
56
|
+
def error messages, args={}
|
55
57
|
code = args.delete(:code)
|
56
58
|
status = args.delete(:status)
|
57
59
|
|
@@ -59,11 +61,18 @@ class Joshua
|
|
59
61
|
|
60
62
|
@status ||= status if status
|
61
63
|
|
62
|
-
text = text.to_s
|
63
|
-
|
64
64
|
@errors[:code] ||= code if code
|
65
65
|
@errors[:messages] ||= []
|
66
|
-
|
66
|
+
|
67
|
+
unless messages.class == Array
|
68
|
+
messages = [messages.to_s]
|
69
|
+
end
|
70
|
+
|
71
|
+
for text in messages
|
72
|
+
if text.present? && text[0, 2] != '["' && !@errors[:messages].include?(text)
|
73
|
+
@errors[:messages].push text
|
74
|
+
end
|
75
|
+
end
|
67
76
|
end
|
68
77
|
|
69
78
|
def error?
|
data/lib/joshua.rb
CHANGED
@@ -1,22 +1,6 @@
|
|
1
|
-
unless ''.respond_to?(:
|
2
|
-
require '
|
3
|
-
|
4
|
-
class String
|
5
|
-
%w(
|
6
|
-
classify
|
7
|
-
constantize
|
8
|
-
dasherize
|
9
|
-
ordinalize
|
10
|
-
pluralize
|
11
|
-
singularize
|
12
|
-
tableize
|
13
|
-
underscore
|
14
|
-
).each do |name|
|
15
|
-
define_method name do
|
16
|
-
Dry::Inflector.new.send(name, self)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
1
|
+
unless ''.respond_to?(:classify)
|
2
|
+
require 'sequel'
|
3
|
+
Sequel.extension :inflector
|
20
4
|
end
|
21
5
|
|
22
6
|
require 'json'
|
@@ -30,7 +14,7 @@ require_relative './joshua/response'
|
|
30
14
|
require_relative './joshua/render_proxy'
|
31
15
|
|
32
16
|
require_relative './doc/doc'
|
33
|
-
require_relative './doc/
|
17
|
+
require_relative './doc/postman_schema'
|
34
18
|
|
35
19
|
|
36
20
|
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: joshua
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dino Reic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-10-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: dry-inflector
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: json
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,20 +80,6 @@ dependencies:
|
|
94
80
|
- - ">="
|
95
81
|
- !ruby/object:Gem::Version
|
96
82
|
version: '0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: http
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
104
|
-
type: :runtime
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - ">="
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
111
83
|
description: Ruby language based, framework agnostic API request/response lib
|
112
84
|
email: rejotl@gmail.com
|
113
85
|
executables: []
|
@@ -115,9 +87,8 @@ extensions: []
|
|
115
87
|
extra_rdoc_files: []
|
116
88
|
files:
|
117
89
|
- "./.version"
|
118
|
-
- "./lib/.DS_Store"
|
119
90
|
- "./lib/doc/doc.rb"
|
120
|
-
- "./lib/doc/
|
91
|
+
- "./lib/doc/postman_schema.rb"
|
121
92
|
- "./lib/joshua.rb"
|
122
93
|
- "./lib/joshua/base_class.rb"
|
123
94
|
- "./lib/joshua/base_instance.rb"
|
@@ -146,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
117
|
- !ruby/object:Gem::Version
|
147
118
|
version: '0'
|
148
119
|
requirements: []
|
149
|
-
rubygems_version: 3.
|
120
|
+
rubygems_version: 3.5.9
|
150
121
|
signing_key:
|
151
122
|
specification_version: 4
|
152
123
|
summary: Joshua
|
data/lib/.DS_Store
DELETED
Binary file
|