praxis 0.20.1 → 0.21
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/.travis.yml +2 -2
- data/CHANGELOG.md +36 -0
- data/lib/api_browser/Gruntfile.js +33 -3
- data/lib/api_browser/app/index.html +3 -0
- data/lib/api_browser/app/js/factories/Example.js +4 -0
- data/lib/api_browser/app/js/factories/template_for.js +14 -0
- data/lib/api_browser/app/js/filters/attribute_name.js +3 -2
- data/lib/api_browser/app/js/filters/header_info.js +9 -0
- data/lib/api_browser/app/views/action.html +11 -2
- data/lib/api_browser/app/views/controller.html +5 -5
- data/lib/api_browser/app/views/menu.html +1 -1
- data/lib/api_browser/app/views/type.html +4 -23
- data/lib/api_browser/app/views/type/details.html +7 -4
- data/lib/api_browser/app/views/types/main/array.html +22 -0
- data/lib/api_browser/app/views/types/main/default.html +23 -0
- data/lib/api_browser/app/views/types/main/hash.html +23 -0
- data/lib/praxis.rb +2 -0
- data/lib/praxis/action_definition.rb +0 -8
- data/lib/praxis/api_definition.rb +11 -6
- data/lib/praxis/api_general_info.rb +13 -0
- data/lib/praxis/bootloader.rb +11 -5
- data/lib/praxis/docs/generator.rb +31 -11
- data/lib/praxis/docs/link_builder.rb +30 -0
- data/lib/praxis/extensions/field_expansion.rb +2 -2
- data/lib/praxis/media_type.rb +1 -1
- data/lib/praxis/middleware_app.rb +30 -0
- data/lib/praxis/resource_definition.rb +24 -2
- data/lib/praxis/response.rb +2 -1
- data/lib/praxis/response_definition.rb +2 -2
- data/lib/praxis/responses/http.rb +28 -92
- data/lib/praxis/responses/validation_error.rb +4 -1
- data/lib/praxis/tasks/api_docs.rb +11 -24
- data/lib/praxis/trait.rb +12 -7
- data/lib/praxis/validation_handler.rb +2 -1
- data/lib/praxis/version.rb +1 -1
- data/praxis.gemspec +11 -7
- data/spec/api_browser/filters/attribute_name_spec.js +2 -2
- data/spec/praxis/action_definition_spec.rb +23 -1
- data/spec/praxis/bootloader_spec.rb +28 -0
- data/spec/praxis/extensions/field_expansion_spec.rb +10 -0
- data/spec/praxis/middleware_app_spec.rb +55 -0
- data/spec/praxis/plugins/praxis_mapper_plugin_spec.rb +8 -3
- data/spec/praxis/resource_definition_spec.rb +51 -2
- data/spec/praxis/response_definition_spec.rb +16 -4
- data/spec/praxis/response_spec.rb +1 -1
- data/spec/praxis/trait_spec.rb +13 -0
- data/spec/spec_app/config/environment.rb +11 -1
- metadata +30 -25
- data/lib/praxis/restful_doc_generator.rb +0 -439
@@ -78,6 +78,19 @@ module Praxis
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
+
def documentation_url(val=nil)
|
82
|
+
if val.nil?
|
83
|
+
get(:documentation_url)
|
84
|
+
else
|
85
|
+
if @global_info.nil? # this *is* the global info
|
86
|
+
set(:documentation_url, val)
|
87
|
+
else
|
88
|
+
raise "Use of documentation_url is only allowed in the global part of " \
|
89
|
+
"the API definition (but you are attempting to use it in the API " \
|
90
|
+
"definition of version #{self.version}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
81
94
|
|
82
95
|
def base_path(val=nil)
|
83
96
|
if val
|
data/lib/praxis/bootloader.rb
CHANGED
@@ -93,15 +93,21 @@ module Praxis
|
|
93
93
|
instance.options.merge!(options)
|
94
94
|
instance.block = block if block_given?
|
95
95
|
|
96
|
-
if
|
97
|
-
raise "
|
96
|
+
config_key = if instance.config_key.nil?
|
97
|
+
raise "Cannot use plugin: #{plugin}. It does not have a config_key defined, and its class does not have a name" unless instance.class.name
|
98
|
+
# Default the config key based on the full class name transformed to snake case (and joining modules with '_')
|
99
|
+
instance.class.name.to_s.split('::').collect{|n| n.underscore }.join('_').to_sym
|
100
|
+
else
|
101
|
+
instance.config_key
|
98
102
|
end
|
99
103
|
|
100
|
-
if instance.config_key
|
101
|
-
|
104
|
+
if application.plugins.key?(instance.config_key)
|
105
|
+
used_in = application.plugins[config_key].class
|
106
|
+
raise "Can not use plugin: #{plugin}, another plugin (#{used_in}) is already registered with key: #{instance.config_key}"
|
102
107
|
end
|
103
108
|
|
104
|
-
application.plugins[
|
109
|
+
application.plugins[config_key] = instance
|
110
|
+
|
105
111
|
instance
|
106
112
|
end
|
107
113
|
|
@@ -79,12 +79,15 @@ module Praxis
|
|
79
79
|
end
|
80
80
|
|
81
81
|
|
82
|
-
#
|
83
|
-
#
|
84
|
-
|
82
|
+
# Data: hash/array structure of dumped resources and/or types
|
83
|
+
# processed_types: list of type classes that have already gone through a describe+collect (this or previous rounds)
|
84
|
+
# ... any processed type won't need to be described+reached any longer
|
85
|
+
# newly_found: list of type classes that have been seen in the search (and that weren't already in the processed type)
|
86
|
+
def scan_dump_for_types( data, processed_types )
|
87
|
+
newfound_types = Set.new
|
85
88
|
case data
|
86
89
|
when Array
|
87
|
-
data.collect{|item|
|
90
|
+
data.collect{|item| newfound_types += scan_dump_for_types( item , processed_types ) }
|
88
91
|
when Hash
|
89
92
|
if data.key?(:type) && data[:type].kind_of?(Hash) && ( [:id,:name,:family] - data[:type].keys ).empty?
|
90
93
|
type_id = data[:type][:id]
|
@@ -93,12 +96,12 @@ module Praxis
|
|
93
96
|
raise "Error! We have detected a reference to a 'Type' with id='#{type_id}' which is not derived from Attributor::Type" +
|
94
97
|
" Document generation cannot proceed."
|
95
98
|
end
|
96
|
-
|
99
|
+
newfound_types << types_by_id[type_id] unless processed_types.include? types_by_id[type_id]
|
97
100
|
end
|
98
101
|
end
|
99
|
-
data.values.map{|item|
|
102
|
+
data.values.map{|item| newfound_types += scan_dump_for_types( item , processed_types)}
|
100
103
|
end
|
101
|
-
|
104
|
+
newfound_types
|
102
105
|
end
|
103
106
|
|
104
107
|
def write_index_file( for_versions: )
|
@@ -124,13 +127,30 @@ module Praxis
|
|
124
127
|
dumped_resources = dump_resources( resources_by_version[version] )
|
125
128
|
found_media_types = resources_by_version[version].select{|r| r.media_type}.collect {|r| r.media_type.describe }
|
126
129
|
|
127
|
-
|
128
|
-
|
130
|
+
# We'll start by processing the rendered mediatypes
|
131
|
+
processed_types = Set.new(resources_by_version[version].select do|r|
|
132
|
+
r.media_type && !r.media_type.is_a?(Praxis::SimpleMediaType)
|
133
|
+
end.collect(&:media_type))
|
134
|
+
|
135
|
+
newfound = Set.new
|
129
136
|
found_media_types.each do |mt|
|
130
|
-
|
137
|
+
newfound += scan_dump_for_types( { type: mt} , processed_types )
|
138
|
+
end
|
139
|
+
# Then will process the rendered resources (noting)
|
140
|
+
newfound += scan_dump_for_types( dumped_resources, Set.new )
|
141
|
+
|
142
|
+
# At this point we've done a scan of the dumped resources and mediatypes.
|
143
|
+
# In that scan we've discovered a bunch of types, however, many of those might have appeared in the JSON
|
144
|
+
# rendered in just shallow mode, so it is not guaranteed that we've seen all the available types.
|
145
|
+
# For that we'll do a (non-shallow) dump of all the types we found, and scan them until the scans do not
|
146
|
+
# yield types we haven't seen before
|
147
|
+
while !newfound.empty? do
|
148
|
+
dumped = newfound.collect(&:describe)
|
149
|
+
processed_types += newfound
|
150
|
+
newfound = scan_dump_for_types( dumped, processed_types )
|
131
151
|
end
|
132
152
|
|
133
|
-
dumped_schemas = dump_schemas(
|
153
|
+
dumped_schemas = dump_schemas( processed_types )
|
134
154
|
full_data = {
|
135
155
|
info: version_info[:info],
|
136
156
|
resources: dumped_resources,
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Praxis
|
2
|
+
module Docs
|
3
|
+
# Generates links into the generated doc browser.
|
4
|
+
class LinkBuilder
|
5
|
+
include Singleton
|
6
|
+
|
7
|
+
# Generates a link based on a request gone wrong.
|
8
|
+
# @return [String, nil] The doc browser link.
|
9
|
+
def for_request(req)
|
10
|
+
build_link req.version, 'controller', req.action.resource_definition.id, req.action.name
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def build_link(*segments)
|
16
|
+
if endpoint
|
17
|
+
endpoint + '#' + segments.join('/')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def endpoint
|
22
|
+
@endpoint ||= begin
|
23
|
+
endpoint = ApiDefinition.instance.global_info.documentation_url
|
24
|
+
endpoint.gsub(/\/index\.html$/i, '/') if endpoint
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -17,8 +17,8 @@ module Praxis
|
|
17
17
|
extend ActiveSupport::Concern
|
18
18
|
|
19
19
|
def expanded_fields(request, media_type)
|
20
|
-
use_fields = self.params.attributes.key?(:fields)
|
21
|
-
use_view = self.params.attributes.key?(:view)
|
20
|
+
use_fields = self.params && self.params.attributes.key?(:fields)
|
21
|
+
use_view = self.params && self.params.attributes.key?(:view)
|
22
22
|
|
23
23
|
# Determine what, if any, fields to display.
|
24
24
|
fields = if use_fields
|
data/lib/praxis/media_type.rb
CHANGED
@@ -126,7 +126,7 @@ module Praxis
|
|
126
126
|
end
|
127
127
|
|
128
128
|
# now to tackle whatever links there may be
|
129
|
-
if (links_fields = fields[:links])
|
129
|
+
if defined?(type::Links) &&(links_fields = fields[:links])
|
130
130
|
resolved_links = resolve_links(type::Links, links_fields)
|
131
131
|
self.deep_merge(result, resolved_links)
|
132
132
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Praxis
|
2
|
+
class MiddlewareApp
|
3
|
+
|
4
|
+
attr_reader :target
|
5
|
+
|
6
|
+
# Initialize the application instance with the desired args, and return the wrapping class.
|
7
|
+
def self.for( **args )
|
8
|
+
Praxis::Application.instance.setup(**args)
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize( inner )
|
13
|
+
@target = inner
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
result = Praxis::Application.instance.call(env)
|
18
|
+
|
19
|
+
unless ( [404,405].include?(result[0].to_i) && result[1]['X-Cascade'] == 'pass' )
|
20
|
+
# Respect X-Cascade header if it doesn't specify 'pass'
|
21
|
+
result
|
22
|
+
else
|
23
|
+
last_body = result[2]
|
24
|
+
last_body.close if last_body.respond_to? :close
|
25
|
+
target.call(env)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -11,7 +11,8 @@ module Praxis
|
|
11
11
|
@version = 'n/a'.freeze
|
12
12
|
@actions = Hash.new
|
13
13
|
@responses = Hash.new
|
14
|
-
|
14
|
+
|
15
|
+
@action_defaults = Trait.new &ResourceDefinition.generate_defaults_block
|
15
16
|
|
16
17
|
@version_options = {}
|
17
18
|
@metadata = {}
|
@@ -35,9 +36,28 @@ module Praxis
|
|
35
36
|
Application.instance.resource_definitions << self
|
36
37
|
end
|
37
38
|
|
39
|
+
def self.generate_defaults_block( version: nil )
|
40
|
+
|
41
|
+
# Ensure we inherit any base params defined in the API definition for the passed in version
|
42
|
+
base_attributes = if (base_params = ApiDefinition.instance.info(version).base_params)
|
43
|
+
base_params.attributes
|
44
|
+
else
|
45
|
+
{}
|
46
|
+
end
|
47
|
+
|
48
|
+
Proc.new do
|
49
|
+
unless base_attributes.empty?
|
50
|
+
params do
|
51
|
+
base_attributes.each do |base_name, base_attribute|
|
52
|
+
attribute base_name, base_attribute.type, base_attribute.options
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
38
59
|
def self.finalize!
|
39
60
|
Application.instance.resource_definitions.each do |resource_definition|
|
40
|
-
|
41
61
|
while (block = resource_definition.on_finalize.shift)
|
42
62
|
block.call
|
43
63
|
end
|
@@ -178,6 +198,8 @@ module Praxis
|
|
178
198
|
@version_prefix = "#{Praxis::Request::path_version_prefix}#{self.version}"
|
179
199
|
end
|
180
200
|
end
|
201
|
+
|
202
|
+
@action_defaults.instance_eval &ResourceDefinition.generate_defaults_block( version: version )
|
181
203
|
end
|
182
204
|
|
183
205
|
|
data/lib/praxis/response.rb
CHANGED
@@ -18,11 +18,12 @@ module Praxis
|
|
18
18
|
klass.status = self.status if self.status
|
19
19
|
end
|
20
20
|
|
21
|
-
def initialize(status:self.class.status, headers:{}, body:'')
|
21
|
+
def initialize(status:self.class.status, headers:{}, body:'', location: nil)
|
22
22
|
@name = response_name
|
23
23
|
@status = status
|
24
24
|
@headers = headers
|
25
25
|
@body = body
|
26
|
+
@headers['Location'] = location if location
|
26
27
|
@form_data = nil
|
27
28
|
@parts = Hash.new
|
28
29
|
end
|
@@ -147,14 +147,14 @@ module Praxis
|
|
147
147
|
default_handlers.include?(k)
|
148
148
|
end
|
149
149
|
|
150
|
-
if (handler = handlers[identifier.handler_name])
|
150
|
+
if (identifier && handler = handlers[identifier.handler_name])
|
151
151
|
payload[:examples][identifier.handler_name] = {
|
152
152
|
content_type: identifier.to_s,
|
153
153
|
body: handler.generate(rendered_payload)
|
154
154
|
}
|
155
155
|
else
|
156
156
|
handlers.each do |name, handler|
|
157
|
-
content_type = identifier + name
|
157
|
+
content_type = ( identifier ) ? identifier + name : 'application/' + name
|
158
158
|
payload[:examples][name] = {
|
159
159
|
content_type: content_type.to_s,
|
160
160
|
body: handler.generate(rendered_payload)
|
@@ -18,11 +18,6 @@ module Praxis
|
|
18
18
|
# being created.
|
19
19
|
class Created < Praxis::Response
|
20
20
|
self.status = 201
|
21
|
-
|
22
|
-
def initialize(status:self.class.status, headers:{}, body:'', location: nil)
|
23
|
-
super(status: status, headers: headers, body: body)
|
24
|
-
headers['Location'] = location if location
|
25
|
-
end
|
26
21
|
end
|
27
22
|
|
28
23
|
|
@@ -138,94 +133,35 @@ module Praxis
|
|
138
133
|
|
139
134
|
ApiDefinition.define do |api|
|
140
135
|
|
141
|
-
api.response_template :accepted do
|
142
|
-
status 202
|
143
|
-
description "The request has been accepted for processing, but the processing has not been completed."
|
144
|
-
end
|
145
|
-
|
146
|
-
api.response_template :no_content do
|
147
|
-
status 204
|
148
|
-
description "The server successfully processed the request, but is not returning any content."
|
149
|
-
end
|
150
|
-
|
151
|
-
api.response_template :multiple_choices do
|
152
|
-
status 300
|
153
|
-
description "Indicates multiple options for the resource that the client may follow."
|
154
|
-
end
|
155
|
-
|
156
|
-
api.response_template :moved_permanently do
|
157
|
-
status 301
|
158
|
-
description "This and all future requests should be directed to the given URI."
|
159
|
-
end
|
160
|
-
|
161
|
-
api.response_template :found do
|
162
|
-
status 302
|
163
|
-
description "The requested resource resides temporarily under a different URI."
|
164
|
-
end
|
165
|
-
|
166
|
-
api.response_template :see_other do
|
167
|
-
status 303
|
168
|
-
description "The response to the request can be found under another URI using a GET method"
|
169
|
-
end
|
170
|
-
|
171
|
-
api.response_template :not_modified do
|
172
|
-
status 304
|
173
|
-
description "Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or If-Match."
|
174
|
-
end
|
175
|
-
|
176
|
-
api.response_template :temporary_redirect do
|
177
|
-
status 307
|
178
|
-
description "In this case, the request should be repeated with another URI; however, future requests should still use the original URI."
|
179
|
-
end
|
180
|
-
|
181
|
-
api.response_template :bad_request do
|
182
|
-
status 400
|
183
|
-
description "The request cannot be fulfilled due to bad syntax."
|
184
|
-
end
|
185
|
-
|
186
|
-
api.response_template :unauthorized do
|
187
|
-
status 401
|
188
|
-
description "Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided."
|
189
|
-
end
|
190
|
-
|
191
|
-
api.response_template :forbidden do
|
192
|
-
status 403
|
193
|
-
description "The request was a valid request, but the server is refusing to respond to it."
|
194
|
-
end
|
195
|
-
|
196
|
-
api.response_template :not_found do
|
197
|
-
status 404
|
198
|
-
description "The requested resource could not be found but may be available again in the future."
|
199
|
-
end
|
200
|
-
|
201
|
-
api.response_template :method_not_allowed do
|
202
|
-
status 405
|
203
|
-
description "A request was made of a resource using a request method not supported by that resource."
|
204
|
-
end
|
205
|
-
|
206
|
-
api.response_template :not_acceptable do
|
207
|
-
status 406
|
208
|
-
description "The requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request."
|
209
|
-
end
|
210
|
-
|
211
|
-
api.response_template :request_timeout do
|
212
|
-
status 408
|
213
|
-
description "The server timed out waiting for the request."
|
214
|
-
end
|
215
|
-
|
216
|
-
api.response_template :conflict do
|
217
|
-
status 409
|
218
|
-
description "Indicates that the request could not be processed because of conflict in the request, such as an edit conflict in the case of multiple updates."
|
219
|
-
end
|
220
|
-
|
221
|
-
api.response_template :precondition_failed do
|
222
|
-
status 412
|
223
|
-
description "The server does not meet one of the preconditions that the requester put on the request."
|
224
|
-
end
|
225
136
|
|
226
|
-
|
227
|
-
|
228
|
-
|
137
|
+
[
|
138
|
+
[ :accepted, 202, "The request has been accepted for processing, but the processing has not been completed." ],
|
139
|
+
[ :no_content, 204,"The server successfully processed the request, but is not returning any content."],
|
140
|
+
[ :multiple_choices, 300,"Indicates multiple options for the resource that the client may follow."],
|
141
|
+
[ :moved_permanently, 301,"This and all future requests should be directed to the given URI."],
|
142
|
+
[ :found, 302,"The requested resource resides temporarily under a different URI."],
|
143
|
+
[ :see_other, 303,"The response to the request can be found under another URI using a GET method"],
|
144
|
+
[ :not_modified, 304,"Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or If-Match."],
|
145
|
+
[ :temporary_redirect, 307,"In this case, the request should be repeated with another URI; however, future requests should still use the original URI."],
|
146
|
+
[ :bad_request, 400,"The request cannot be fulfilled due to bad syntax."],
|
147
|
+
[ :unauthorized, 401,"Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided."],
|
148
|
+
[ :forbidden, 403,"The request was a valid request, but the server is refusing to respond to it."],
|
149
|
+
[ :not_found, 404,"The requested resource could not be found but may be available again in the future."],
|
150
|
+
[ :method_not_allowed, 405,"A request was made of a resource using a request method not supported by that resource."],
|
151
|
+
[ :not_acceptable, 406,"The requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request."],
|
152
|
+
[ :request_timeout, 408,"The server timed out waiting for the request."],
|
153
|
+
[ :conflict, 409, "Indicates that the request could not be processed because of conflict in the request, such as an edit conflict in the case of multiple updates."],
|
154
|
+
[ :precondition_failed, 412,"The server does not meet one of the preconditions that the requester put on the request."],
|
155
|
+
[ :unprocessable_entity, 422,"The request was well-formed but was unable to be followed due to semantic errors."],
|
156
|
+
].each do |name, code, base_description|
|
157
|
+
api.response_template name do |media_type: nil, location: nil, headers: nil, description: nil|
|
158
|
+
status code
|
159
|
+
description( description || base_description ) # description can "potentially" be overriden in an individual action.
|
160
|
+
|
161
|
+
media_type media_type if media_type
|
162
|
+
location location if location
|
163
|
+
headers headers if headers
|
164
|
+
end
|
229
165
|
end
|
230
166
|
|
231
167
|
end
|
@@ -3,7 +3,7 @@ module Praxis
|
|
3
3
|
module Responses
|
4
4
|
|
5
5
|
class ValidationError < BadRequest
|
6
|
-
def initialize(summary:, errors: nil, exception: nil, **opts)
|
6
|
+
def initialize(summary:, errors: nil, exception: nil, documentation: nil, **opts)
|
7
7
|
super(**opts)
|
8
8
|
@headers['Content-Type'] = 'application/json' #TODO: might want an error mediatype
|
9
9
|
@errors = errors
|
@@ -12,6 +12,7 @@ module Praxis
|
|
12
12
|
end
|
13
13
|
@exception = exception
|
14
14
|
@summary = summary
|
15
|
+
@documentation = documentation
|
15
16
|
end
|
16
17
|
|
17
18
|
def format!
|
@@ -22,6 +23,8 @@ module Praxis
|
|
22
23
|
@body[:cause] = {name: @exception.cause.class.name, message: @exception.cause.message}
|
23
24
|
end
|
24
25
|
|
26
|
+
@body[:documentation] = @documentation if @documentation
|
27
|
+
|
25
28
|
@body
|
26
29
|
end
|
27
30
|
end
|
@@ -1,6 +1,13 @@
|
|
1
1
|
namespace :praxis do
|
2
2
|
|
3
3
|
namespace :docs do
|
4
|
+
|
5
|
+
def base_path
|
6
|
+
require 'uri'
|
7
|
+
documentation_url = Praxis::ApiDefinition.instance.global_info.documentation_url
|
8
|
+
URI(documentation_url).path.gsub(/\/[^\/]*$/, '/') if documentation_url
|
9
|
+
end
|
10
|
+
|
4
11
|
path = File.expand_path(File.join(File.dirname(__FILE__), '../../api_browser'))
|
5
12
|
|
6
13
|
desc "Install dependencies"
|
@@ -32,7 +39,8 @@ namespace :praxis do
|
|
32
39
|
exec({
|
33
40
|
'USER_DOCS_PATH' => File.join(Dir.pwd, 'docs'),
|
34
41
|
'DOC_PORT' => doc_port,
|
35
|
-
'PLUGIN_PATHS' => Praxis::Application.instance.doc_browser_plugin_paths.join(':')
|
42
|
+
'PLUGIN_PATHS' => Praxis::Application.instance.doc_browser_plugin_paths.join(':'),
|
43
|
+
'BASE_PATH' => '/'
|
36
44
|
}, "#{path}/node_modules/.bin/grunt serve --gruntfile '#{path}/Gruntfile.js'")
|
37
45
|
end
|
38
46
|
|
@@ -40,19 +48,11 @@ namespace :praxis do
|
|
40
48
|
task :build => [:install, :generate] do
|
41
49
|
exec({
|
42
50
|
'USER_DOCS_PATH' => File.join(Dir.pwd, 'docs'),
|
43
|
-
'PLUGIN_PATHS' => Praxis::Application.instance.doc_browser_plugin_paths.join(':')
|
51
|
+
'PLUGIN_PATHS' => Praxis::Application.instance.doc_browser_plugin_paths.join(':'),
|
52
|
+
'BASE_PATH' => base_path
|
44
53
|
}, "#{path}/node_modules/.bin/grunt build --gruntfile '#{path}/Gruntfile.js'")
|
45
54
|
end
|
46
55
|
|
47
|
-
desc "Generate deprecated API docs (JSON definitions) for a Praxis App"
|
48
|
-
task :generate_old => [:environment] do |t, args|
|
49
|
-
require 'fileutils'
|
50
|
-
STDERR.puts "DEPRECATION: praxis:docs:generate_old is deprecated and will be removed in the next version. Please update tooling that may need this."
|
51
|
-
|
52
|
-
Praxis::Blueprint.caching_enabled = false
|
53
|
-
generator = Praxis::RestfulDocGenerator.new(Dir.pwd)
|
54
|
-
end
|
55
|
-
|
56
56
|
desc "Generate API docs (JSON definitions) for a Praxis App"
|
57
57
|
task :generate => [:environment] do |t, args|
|
58
58
|
require 'fileutils'
|
@@ -63,17 +63,4 @@ namespace :praxis do
|
|
63
63
|
end
|
64
64
|
|
65
65
|
end
|
66
|
-
|
67
|
-
desc "Generate API docs (JSON definitions) for a Praxis App"
|
68
|
-
task :api_docs do
|
69
|
-
STDERR.puts "DEPRECATION: praxis:api_docs is deprecated and will be removed by 1.0. Please use praxis:docs:generate instead."
|
70
|
-
Rake::Task["praxis:docs:generate_old"].invoke
|
71
|
-
end
|
72
|
-
|
73
|
-
desc "Run API Documentation Browser"
|
74
|
-
task :doc_browser, [:port] do |t, args|
|
75
|
-
STDERR.puts "DEPRECATION: praxis:doc_browser is deprecated and will be removed by 1.0. Please use praxis:docs:preview instead. The doc browser now runs on port 9090."
|
76
|
-
Rake::Task["praxis:docs:preview"].invoke
|
77
|
-
end
|
78
|
-
|
79
66
|
end
|