joshua 0.2.4 → 0.2.7
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/.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
|