useless-doc 0.1.3 → 0.2.0

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.
@@ -0,0 +1,60 @@
1
+ module Useless
2
+ module Doc
3
+ module Core
4
+
5
+ # Documentation for an HTTP body, belonging either to the request or the
6
+ # response.
7
+ #
8
+ # @!attribute [r] content_type
9
+ # @return [String] the MIME type of the body.
10
+ #
11
+ # @!attribute [r] attributes
12
+ # @return [Array<Body::Attribute>] documentation for each of the body
13
+ # attributes.
14
+ #
15
+ class Body
16
+
17
+ attr_reader :content_type, :attributes
18
+
19
+ # @param [Hash] attrs corresponds to the class's instance attributes.
20
+ #
21
+ def initialize(attrs)
22
+ @content_type = attrs[:content_type]
23
+ @attributes = attrs[:attributes]
24
+ end
25
+
26
+ # Documentation for an attribute on an HTTP body.
27
+ #
28
+ # @!attribute [r] key
29
+ # @return [String] the key of this attribute in the body.
30
+ #
31
+ # @!attribute [r] value_type
32
+ # @return [String] one of "string", "number", "object",
33
+ # "array", or "boolean". "string" is the default value.
34
+ #
35
+ # @!attribute [r] required
36
+ # @return [Boolean] whether or not the attribute is required. If it
37
+ # is required, and the attribute is omitted, the response should have
38
+ # a 4xx code. +true+ is the default value.
39
+ #
40
+ # @!attribute [r] description
41
+ # @return [String] a description of the attribute.
42
+ #
43
+ class Attribute
44
+
45
+ attr_reader :key, :type, :required, :default, :description
46
+
47
+ # @param [Hash] attrs corresponds to the class's instance attributes.
48
+ #
49
+ def initialize(attrs)
50
+ @key = attrs[:key]
51
+ @type = attrs[:type] || 'string'
52
+ @required = attrs.key?(:required) ? attrs[:required] : true
53
+ @default = attrs[:default]
54
+ @description = attrs[:description]
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,26 @@
1
+ module Useless
2
+ module Doc
3
+ module Core
4
+
5
+ # Documentation for an HTTP header, belonging either to the request or the
6
+ # response.
7
+ #
8
+ # @!attribute [r] key
9
+ # @return [String] the key of the header.
10
+ #
11
+ # @!attribute [r] description
12
+ # @return [String] a description of the header.
13
+ #
14
+ class Header
15
+ attr_accessor :key, :description
16
+
17
+ # @param [Hash] attrs corresponds to the class's instance attributes.
18
+ #
19
+ def initialize(attrs = {})
20
+ @key = attrs[:key]
21
+ @description = attrs[:description]
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,106 @@
1
+ module Useless
2
+ module Doc
3
+ module Core
4
+
5
+ # Documentation for an HTTP request.
6
+ #
7
+ # @!attribute [r] method
8
+ # @return [String] the request's HTTP method.
9
+ # @see Useless::Doc::Core::Request::Method
10
+ #
11
+ # @!attribute [r] description
12
+ # @return [String] a description of the request.
13
+ #
14
+ # @!attribute [r] authentication_required
15
+ # @return [Boolean] whether or not the user needs to authenticate in
16
+ # order to perform this request.
17
+ #
18
+ # @!attribute [r] parameters
19
+ # @return [Array<Request::Parameter>] possible parameters for the
20
+ # request.
21
+ # @see Useless::Doc::Core::Request::Parameter
22
+ #
23
+ # @!attribute [r] headers
24
+ # @return [Array<Header>] possible headers for the request.
25
+ # @see Useless::Doc::Core::Heaader
26
+ #
27
+ # @!attribute [r] body
28
+ # @return [Body] the body of the request.
29
+ # @see Useless::Doc::Core::Body
30
+ #
31
+ # @!attribute [r] responses
32
+ # @return [Array<Response>] possible responses to the request.
33
+ # @see Useless::Doc::Core::Response
34
+ #
35
+ class Request
36
+
37
+ module Method
38
+ GET = 'GET'
39
+ HEAD = 'HEAD'
40
+ POST = 'POST'
41
+ PUT = 'PUT'
42
+ PATCH = 'PATCH'
43
+ DELETE = 'DELETE'
44
+ TRACE = 'TRACE'
45
+ CONNECT = 'CONNECT'
46
+ end
47
+
48
+ attr_accessor :method, :description, :authentication_required,
49
+ :parameters, :headers, :body, :responses
50
+
51
+ # @param [Hash] attrs corresponds to the class's instance attributes.
52
+ #
53
+ def initialize(attrs = {})
54
+ @method = attrs[:method]
55
+ @description = attrs[:description]
56
+ @authentication_required = attrs[:authentication_required]
57
+ @parameters = attrs[:parameters]
58
+ @headers = attrs[:headers]
59
+ @body = attrs[:body]
60
+ @responses = attrs[:responses]
61
+ end
62
+
63
+ # Documentation for a request parameter for an API action.
64
+ #
65
+ # @!attribute [r] type
66
+ # @return [String] either "path" if it's part of the URL path, or
67
+ # "query" if it's part of the query string.
68
+ #
69
+ # @!attribute [r] key
70
+ # @return [String] the key of the parameter.
71
+ #
72
+ # @!attribute [r] required
73
+ # @return [Boolean] whether or not the parameter is required. If it is
74
+ # required, and the attribute is omitted, the response should have a
75
+ # 4xx code.
76
+ #
77
+ # @!attribute [r] default
78
+ # @return [String, Numeric] the value used if the parameter is omitted
79
+ # and is not required.
80
+ #
81
+ # @!attribute [r] description
82
+ # @return [String] a description of the parameter.
83
+ #
84
+ class Parameter
85
+
86
+ module Type
87
+ PATH = 'path'
88
+ QUERY = 'query'
89
+ end
90
+
91
+ attr_reader :type, :key, :required, :default, :description
92
+
93
+ # @param [Hash] attrs corresponds to the class's instance attributes.
94
+ #
95
+ def initialize(attrs = {})
96
+ @type = attrs[:type]
97
+ @key = attrs[:key]
98
+ @required = attrs[:required]
99
+ @default = attrs[:default]
100
+ @description = attrs[:description]
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,32 @@
1
+ module Useless
2
+ module Doc
3
+ module Core
4
+
5
+ # Documentation for an API resource.
6
+ #
7
+ # @!attribute [r] path
8
+ # @return [String] the path segment of the resource URL.
9
+ #
10
+ # @!attribute [r] description
11
+ # @return [String] a description of the resource.
12
+ #
13
+ # @!attribute [r] requests
14
+ # @return [Array<Request>] requests that could possibly be made
15
+ # against this resource.
16
+ # @see Useless::Doc::Core::Request
17
+ #
18
+ class Resource
19
+
20
+ attr_reader :path, :description, :requests
21
+
22
+ # @param [Hash] attrs corresponds to the class's instance attributes.
23
+ #
24
+ def initialize(attrs = {})
25
+ @path = attrs[:path]
26
+ @description = attrs[:description]
27
+ @requests = attrs[:requests]
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,8 +1,8 @@
1
1
  module Useless
2
2
  module Doc
3
- class Response
3
+ module Core
4
4
 
5
- # Documentation for a response status for an API action.
5
+ # Documentation for an HTTP response.
6
6
  #
7
7
  # @!attribute [r] code
8
8
  # @return [Integer] the HTTP status code of the response.
@@ -11,15 +11,23 @@ module Useless
11
11
  # @return [String] a description of the rationale for
12
12
  # the response.
13
13
  #
14
- class Status
15
-
16
- attr_reader :code, :description
14
+ # @!attribute [r] headers
15
+ # @return [Array<Header>] the significant headers of the response.
16
+ # @see Useless::Doc::Core::Header
17
+ #
18
+ # @!attribute [r] body
19
+ # @return [Body] the body of the response.
20
+ #
21
+ class Response
22
+ attr_accessor :code, :description, :status, :headers, :body
17
23
 
18
24
  # @param [Hash] attrs corresponds to the class's instance attributes.
19
25
  #
20
26
  def initialize(attrs = {})
21
27
  @code = attrs[:code]
22
28
  @description = attrs[:description]
29
+ @headers = attrs[:headers]
30
+ @body = attrs[:body]
23
31
  end
24
32
  end
25
33
  end
@@ -1,11 +1,8 @@
1
- require 'useless/doc/action'
2
- require 'useless/doc/body'
3
- require 'useless/doc/header'
4
- require 'useless/doc/request'
5
- require 'useless/doc/request/parameter'
6
- require 'useless/doc/resource'
7
- require 'useless/doc/response'
8
- require 'useless/doc/response/status'
1
+ require 'useless/doc/core/body'
2
+ require 'useless/doc/core/header'
3
+ require 'useless/doc/core/request'
4
+ require 'useless/doc/core/resource'
5
+ require 'useless/doc/core/response'
9
6
 
10
7
  module Useless
11
8
  module Doc
@@ -19,15 +16,10 @@ module Useless
19
16
  #
20
17
  # get 'Returns a full listing of the resources.' do
21
18
  # authentication_required false
19
+ # parameter 'page', 'The page of resources to be returned.'
20
+ # header 'X-Twiddle', 'The twiddle threshold.'
22
21
  #
23
- # request do
24
- # parameter 'page', 'The page of resources to be returned.'
25
- # header 'X-Twiddle', 'The twiddle threshold.'
26
- # end
27
- #
28
- # response do
29
- # status 200, 'The resources were returned successfully.'
30
- #
22
+ # response 200, 'The resources were returned successfully.' do
31
23
  # header 'X-Twonk', 'The twonk coefficient.'
32
24
  #
33
25
  # body do
@@ -44,7 +36,7 @@ module Useless
44
36
  module ClassMethods
45
37
  def build(attributes = {}, &block)
46
38
  resource = new(attributes)
47
- resource.instance_eval(&block)
39
+ resource.instance_eval(&block) if block_given?
48
40
  resource.generate
49
41
  end
50
42
  end
@@ -59,7 +51,7 @@ module Useless
59
51
 
60
52
  def generate
61
53
  name = self.class.name.split('::').last
62
- klass = eval("Doc::#{name}")
54
+ klass = eval("Doc::Core::#{name}")
63
55
  klass.new(@attributes)
64
56
  end
65
57
 
@@ -72,7 +64,7 @@ module Useless
72
64
  include DSL::Member
73
65
 
74
66
  def default_attributes
75
- { actions: [] }
67
+ { requests: [] }
76
68
  end
77
69
 
78
70
  def path(path)
@@ -84,48 +76,52 @@ module Useless
84
76
  end
85
77
 
86
78
  def get(description = nil, &block)
87
- method(Doc::Action::Method::GET, description, &block)
79
+ method(Doc::Core::Request::Method::GET, description, &block)
88
80
  end
89
81
 
90
82
  def head(description = nil, &block)
91
- method(Doc::Action::Method::HEAD, description, &block)
83
+ method(Doc::Core::Request::Method::HEAD, description, &block)
92
84
  end
93
85
 
94
86
  def post(description = nil, &block)
95
- method(Doc::Action::Method::POST, description, &block)
87
+ method(Doc::Core::Request::Method::POST, description, &block)
96
88
  end
97
89
 
98
90
  def put(description = nil, &block)
99
- method(Doc::Action::Method::PUT, description, &block)
91
+ method(Doc::Core::Request::Method::PUT, description, &block)
100
92
  end
101
93
 
102
94
  def patch(description = nil, &block)
103
- method(Doc::Action::Method::PATCH, description, &block)
95
+ method(Doc::Core::Request::Method::PATCH, description, &block)
104
96
  end
105
97
 
106
98
  def delete(description = nil, &block)
107
- method(Doc::Action::Method::DELETE, description, &block)
99
+ method(Doc::Core::Request::Method::DELETE, description, &block)
108
100
  end
109
101
 
110
102
  def trace(description = nil, &block)
111
- method(Doc::Action::Method::TRACE, description, &block)
103
+ method(Doc::Core::Request::Method::TRACE, description, &block)
112
104
  end
113
105
 
114
106
  def connect(description = nil, &block)
115
- method(Doc::Action::Method::CONNECT, description, &block)
107
+ method(Doc::Core::Request::Method::CONNECT, description, &block)
116
108
  end
117
109
 
118
110
  private
119
111
 
120
112
  def method(type, description, &block)
121
113
  attributes = { method: type, description: description }
122
- @attributes[:actions] << Action.build(attributes, &block)
114
+ @attributes[:requests] << Request.build(attributes, &block)
123
115
  end
124
116
  end
125
117
 
126
- class Action
118
+ class Request
127
119
  include DSL::Member
128
120
 
121
+ def default_attributes
122
+ { parameters: [], headers: [], responses: [] }
123
+ end
124
+
129
125
  def description(description)
130
126
  @attributes[:description] = description
131
127
  end
@@ -134,51 +130,43 @@ module Useless
134
130
  @attributes[:authentication_required] = value.nil? ? true : value
135
131
  end
136
132
 
137
- def request(&block)
138
- @attributes[:request] = Request.build({}, &block)
139
- end
140
-
141
- def response(&block)
142
- @attributes[:response] = Response.build({}, &block)
143
- end
144
- end
145
-
146
- class Request
147
- include DSL::Member
148
-
149
- def default_attributes
150
- { parameters: [], headers: [] }
151
- end
152
-
153
133
  def parameter(key, description, attributes = {})
154
- parameter = Doc::Request::Parameter.new attributes.merge(key: key, description: description)
134
+ parameter = Doc::Core::Request::Parameter.new attributes.merge(key: key, description: description)
155
135
  @attributes[:parameters] << parameter
156
136
  end
157
137
 
158
138
  def header(key, description)
159
- header = Doc::Header.new key: key, description: description
139
+ header = Doc::Core::Header.new key: key, description: description
160
140
  @attributes[:headers] << header
161
141
  end
162
142
 
163
143
  def body(&block)
164
144
  @attributes[:body] = Body.build({}, &block)
165
145
  end
146
+
147
+ def response(code, description, &block)
148
+ response = Response.build({ code: code, description: description }, &block)
149
+ @attributes[:responses] << response
150
+ end
166
151
  end
167
152
 
168
153
  class Response
169
154
  include DSL::Member
170
155
 
171
156
  def default_attributes
172
- { statuses: [], headers: [] }
157
+ { headers: [] }
158
+ end
159
+
160
+ def code(code)
161
+ @attributes[:code] = code
173
162
  end
174
163
 
175
- def status(code, description)
176
- status = Doc::Response::Status.new code: code, description: description
177
- @attributes[:statuses] << status
164
+ def description(description)
165
+ @attributes[:description] = description
178
166
  end
179
167
 
180
168
  def header(key, description)
181
- header = Doc::Header.new key: key, description: description
169
+ header = Doc::Core::Header.new key: key, description: description
182
170
  @attributes[:headers] << header
183
171
  end
184
172
 
@@ -199,7 +187,7 @@ module Useless
199
187
  end
200
188
 
201
189
  def attribute(key, description, attributes = {})
202
- attribute = Doc::Body::Attribute.new attributes.merge(key: key, description: description)
190
+ attribute = Doc::Core::Body::Attribute.new attributes.merge(key: key, description: description)
203
191
  @attributes[:attributes] << attribute
204
192
  end
205
193
  end
@@ -1,5 +1,4 @@
1
1
  require 'uri'
2
- require 'typhoeus'
3
2
  require 'rack/request'
4
3
 
5
4
  module Useless
@@ -39,7 +38,7 @@ module Useless
39
38
 
40
39
  request = ::Rack::Request.new(env)
41
40
 
42
- if valid_subdomain?(request.url)
41
+ if true or valid_subdomain?(request.url)
43
42
  url = Proxy.transform_url(request.url)
44
43
 
45
44
  if json = env['useless.doc.retriever'].retrieve(url)
@@ -1,3 +1,5 @@
1
+ require 'typhoeus'
2
+
1
3
  module Useless
2
4
  module Doc
3
5
  module Rack
@@ -29,19 +29,7 @@ module Useless
29
29
  hash_to_json \
30
30
  'path' => resource.path,
31
31
  'description' => resource.description,
32
- 'actions' => resource.actions.map { |action| action(action) }
33
- end
34
- end
35
-
36
- # @api private
37
- def self.action(action)
38
- if action
39
- hash_to_json \
40
- 'description' => action.description,
41
- 'method' => action.method,
42
- 'authentication_required' => action.authentication_required,
43
- 'request' => request(action.request),
44
- 'response' => response(action.response)
32
+ 'requests' => resource.requests.map { |request| request(request) }
45
33
  end
46
34
  end
47
35
 
@@ -49,9 +37,13 @@ module Useless
49
37
  def self.request(request)
50
38
  if request
51
39
  hash_to_json \
40
+ 'method' => request.method,
41
+ 'description' => request.description,
42
+ 'authentication_required' => request.authentication_required,
52
43
  'parameters' => request.parameters.map { |parameter| request_parameter(parameter) },
53
44
  'headers' => request.headers.map { |header| header(header) },
54
- 'body' => body(request.body)
45
+ 'body' => body(request.body),
46
+ 'responses' => request.responses.map { |response| response(response) }
55
47
  end
56
48
  end
57
49
 
@@ -59,7 +51,8 @@ module Useless
59
51
  def self.response(response)
60
52
  if response
61
53
  hash_to_json \
62
- 'statuses' => response.statuses.map { |status| response_status(status) },
54
+ 'code' => response.code,
55
+ 'description' => response.description,
63
56
  'headers' => response.headers.map { |header| header(header) },
64
57
  'body' => body(response.body)
65
58
  end
@@ -1,13 +1,10 @@
1
1
  require 'oj'
2
2
 
3
- require 'useless/doc/action'
4
- require 'useless/doc/body'
5
- require 'useless/doc/header'
6
- require 'useless/doc/request'
7
- require 'useless/doc/request/parameter'
8
- require 'useless/doc/resource'
9
- require 'useless/doc/response'
10
- require 'useless/doc/response/status'
3
+ require 'useless/doc/core/body'
4
+ require 'useless/doc/core/header'
5
+ require 'useless/doc/core/request'
6
+ require 'useless/doc/core/resource'
7
+ require 'useless/doc/core/response'
11
8
 
12
9
  module Useless
13
10
  module Doc
@@ -37,34 +34,14 @@ module Useless
37
34
  def self.resource(json)
38
35
  hash = json_to_hash json
39
36
 
40
- actions = (hash['actions'] || []).map do |json|
41
- action(json)
37
+ requests = (hash['requests'] || []).map do |json|
38
+ request json
42
39
  end
43
40
 
44
- Useless::Doc::Resource.new \
41
+ Useless::Doc::Core::Resource.new \
45
42
  path: hash['path'],
46
43
  description: hash['description'],
47
- actions: actions
48
- end
49
-
50
- # @api private
51
- def self.action(json)
52
- hash = json_to_hash json
53
-
54
- if hash['request']
55
- request = request hash['request']
56
- end
57
-
58
- if hash['response']
59
- response = response hash['response']
60
- end
61
-
62
- Useless::Doc::Action.new \
63
- description: hash['description'],
64
- method: hash['method'],
65
- authentication_required: hash['authentication_required'],
66
- request: request,
67
- response: response
44
+ requests: requests
68
45
  end
69
46
 
70
47
  # @api private
@@ -83,20 +60,24 @@ module Useless
83
60
  body = body hash['body']
84
61
  end
85
62
 
86
- Useless::Doc::Request.new \
87
- parameters: parameters,
88
- headers: headers,
89
- body: body
63
+ responses = (hash['responses'] || []).map do |json|
64
+ response json
65
+ end
66
+
67
+ Useless::Doc::Core::Request.new \
68
+ method: hash['method'],
69
+ description: hash['description'],
70
+ authentication_required: hash['authentication_required'],
71
+ parameters: parameters,
72
+ headers: headers,
73
+ body: body,
74
+ responses: responses
90
75
  end
91
76
 
92
77
  # @api private
93
78
  def self.response(json)
94
79
  hash = json_to_hash json
95
80
 
96
- statuses = (hash['statuses'] || []).map do |json|
97
- response_statuses json
98
- end
99
-
100
81
  headers = (hash['headers'] || []).map do |json|
101
82
  header json
102
83
  end
@@ -105,17 +86,18 @@ module Useless
105
86
  body = body hash['body']
106
87
  end
107
88
 
108
- Useless::Doc::Response.new \
109
- statuses: statuses,
110
- headers: headers,
111
- body: body
89
+ Useless::Doc::Core::Response.new \
90
+ code: hash['code'],
91
+ description: hash['description'],
92
+ headers: headers,
93
+ body: body
112
94
  end
113
95
 
114
96
  # @api private
115
97
  def self.request_parameter(json)
116
98
  hash = json_to_hash json
117
99
 
118
- Useless::Doc::Request::Parameter.new \
100
+ Useless::Doc::Core::Request::Parameter.new \
119
101
  type: hash['type'],
120
102
  key: hash['key'],
121
103
  required: hash['required'],
@@ -127,7 +109,7 @@ module Useless
127
109
  def self.header(json)
128
110
  hash = json_to_hash json
129
111
 
130
- Useless::Doc::Header.new \
112
+ Useless::Doc::Core::Header.new \
131
113
  key: hash['key'],
132
114
  description: hash['description']
133
115
  end
@@ -140,7 +122,7 @@ module Useless
140
122
  body_attribute json
141
123
  end
142
124
 
143
- Useless::Doc::Body.new \
125
+ Useless::Doc::Core::Body.new \
144
126
  content_type: hash['content_type'],
145
127
  attributes: attributes
146
128
  end
@@ -149,22 +131,13 @@ module Useless
149
131
  def self.body_attribute(json)
150
132
  hash = json_to_hash json
151
133
 
152
- Useless::Doc::Body::Attribute.new \
134
+ Useless::Doc::Core::Body::Attribute.new \
153
135
  key: hash['key'],
154
136
  type: hash['type'],
155
137
  required: hash['required'],
156
138
  default: hash['default'],
157
139
  description: hash['description']
158
140
  end
159
-
160
- # @api private
161
- def self.response_statuses(json)
162
- hash = json_to_hash json
163
-
164
- Useless::Doc::Response::Status.new \
165
- code: hash['code'],
166
- description: hash['description']
167
- end
168
141
  end
169
142
  end
170
143
  end