praxis 0.21 → 0.22.pre.1
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 +5 -5
- data/.travis.yml +20 -12
- data/CHANGELOG.md +24 -0
- data/CONTRIBUTING.md +4 -4
- data/README.md +11 -9
- data/lib/api_browser/app/js/directives/attribute_table.js +2 -1
- data/lib/api_browser/app/js/directives/conditional_requirements.js +13 -0
- data/lib/api_browser/app/js/directives/type_placeholder.js +10 -1
- data/lib/api_browser/app/js/factories/normalize_attributes.js +4 -2
- data/lib/api_browser/app/js/factories/template_for.js +5 -2
- data/lib/api_browser/app/js/filters/has_requirement.js +14 -0
- data/lib/api_browser/app/js/filters/tag_requirement.js +13 -0
- data/lib/api_browser/app/sass/praxis.scss +11 -0
- data/lib/api_browser/app/views/action.html +2 -2
- data/lib/api_browser/app/views/directives/attribute_description/member_options.html +2 -2
- data/lib/api_browser/app/views/directives/attribute_table.html +1 -1
- data/lib/api_browser/app/views/type.html +1 -1
- data/lib/api_browser/app/views/type/details.html +2 -2
- data/lib/api_browser/app/views/types/embedded/array.html +2 -0
- data/lib/api_browser/app/views/types/embedded/default.html +3 -1
- data/lib/api_browser/app/views/types/embedded/requirements.html +6 -0
- data/lib/api_browser/app/views/types/embedded/single_req.html +9 -0
- data/lib/api_browser/app/views/types/embedded/struct.html +14 -2
- data/lib/api_browser/app/views/types/standalone/array.html +1 -1
- data/lib/api_browser/app/views/types/standalone/struct.html +2 -1
- data/lib/api_browser/package.json +1 -1
- data/lib/praxis.rb +8 -6
- data/lib/praxis/action_definition.rb +9 -7
- data/lib/praxis/api_definition.rb +44 -27
- data/lib/praxis/api_general_info.rb +3 -2
- data/lib/praxis/application.rb +139 -20
- data/lib/praxis/bootloader.rb +2 -4
- data/lib/praxis/bootloader_stages/environment.rb +0 -13
- data/lib/praxis/controller.rb +2 -0
- data/lib/praxis/dispatcher.rb +16 -10
- data/lib/praxis/docs/generator.rb +20 -9
- data/lib/praxis/docs/link_builder.rb +1 -1
- data/lib/praxis/error_handler.rb +5 -5
- data/lib/praxis/extensions/attribute_filtering.rb +28 -0
- data/lib/praxis/extensions/attribute_filtering/active_record_filter_query_builder.rb +180 -0
- data/lib/praxis/extensions/attribute_filtering/filtering_params.rb +273 -0
- data/lib/praxis/extensions/attribute_filtering/query_builder.rb +39 -0
- data/lib/praxis/extensions/field_selection.rb +3 -0
- data/lib/praxis/extensions/field_selection/active_record_query_selector.rb +57 -0
- data/lib/praxis/extensions/field_selection/sequel_query_selector.rb +65 -0
- data/lib/praxis/extensions/rails_compat.rb +2 -0
- data/lib/praxis/extensions/rails_compat/request_methods.rb +19 -0
- data/lib/praxis/extensions/rendering.rb +1 -1
- data/lib/praxis/file_group.rb +1 -1
- data/lib/praxis/middleware_app.rb +26 -6
- data/lib/praxis/multipart/parser.rb +14 -2
- data/lib/praxis/multipart/part.rb +5 -3
- data/lib/praxis/plugins/praxis_mapper_plugin.rb +2 -2
- data/lib/praxis/plugins/rails_plugin.rb +104 -0
- data/lib/praxis/request.rb +8 -9
- data/lib/praxis/request_stages/response.rb +3 -2
- data/lib/praxis/request_superclassing.rb +11 -0
- data/lib/praxis/resource_definition.rb +14 -10
- data/lib/praxis/response.rb +6 -7
- data/lib/praxis/response_definition.rb +7 -5
- data/lib/praxis/response_template.rb +4 -3
- data/lib/praxis/responses/http.rb +0 -36
- data/lib/praxis/responses/internal_server_error.rb +3 -12
- data/lib/praxis/responses/multipart_ok.rb +4 -11
- data/lib/praxis/responses/validation_error.rb +1 -10
- data/lib/praxis/router.rb +3 -3
- data/lib/praxis/tasks/api_docs.rb +10 -2
- data/lib/praxis/tasks/routes.rb +1 -0
- data/lib/praxis/version.rb +1 -1
- data/praxis.gemspec +4 -5
- data/spec/functional_spec.rb +4 -6
- data/spec/praxis/action_definition_spec.rb +26 -15
- data/spec/praxis/api_definition_spec.rb +13 -8
- data/spec/praxis/api_general_info_spec.rb +3 -8
- data/spec/praxis/application_spec.rb +13 -7
- data/spec/praxis/middleware_app_spec.rb +24 -10
- data/spec/praxis/request_spec.rb +17 -7
- data/spec/praxis/request_stages/validate_spec.rb +1 -1
- data/spec/praxis/resource_definition_spec.rb +12 -10
- data/spec/praxis/response_definition_spec.rb +22 -5
- data/spec/praxis/response_spec.rb +12 -5
- data/spec/praxis/responses/internal_server_error_spec.rb +4 -7
- data/spec/praxis/responses/validation_error_spec.rb +2 -2
- data/spec/praxis/router_spec.rb +8 -4
- data/spec/spec_app/config.ru +1 -6
- data/spec/spec_helper.rb +3 -3
- data/tasks/thor/templates/generator/empty_app/Gemfile +3 -3
- metadata +36 -32
- data/.ruby-version +0 -1
- data/lib/praxis/stats.rb +0 -113
- data/spec/praxis/stats_spec.rb +0 -9
|
@@ -12,6 +12,7 @@ module Praxis
|
|
|
12
12
|
|
|
13
13
|
attr_reader :name
|
|
14
14
|
attr_reader :resource_definition
|
|
15
|
+
attr_reader :api_definition
|
|
15
16
|
attr_reader :routes
|
|
16
17
|
attr_reader :primary_route
|
|
17
18
|
attr_reader :named_routes
|
|
@@ -39,6 +40,7 @@ module Praxis
|
|
|
39
40
|
@metadata = Hash.new
|
|
40
41
|
@routes = []
|
|
41
42
|
@traits = []
|
|
43
|
+
@api_definition = resource_definition.application.api_definition
|
|
42
44
|
|
|
43
45
|
if (media_type = resource_definition.media_type)
|
|
44
46
|
if media_type.kind_of?(Class) && media_type < Praxis::Types::MediaTypeCommon
|
|
@@ -47,7 +49,7 @@ module Praxis
|
|
|
47
49
|
end
|
|
48
50
|
|
|
49
51
|
version = resource_definition.version
|
|
50
|
-
api_info =
|
|
52
|
+
api_info = api_definition.info(resource_definition.version)
|
|
51
53
|
|
|
52
54
|
route_base = "#{api_info.base_path}#{resource_definition.version_prefix}"
|
|
53
55
|
prefix = Array(resource_definition.routing_prefix)
|
|
@@ -64,11 +66,11 @@ module Praxis
|
|
|
64
66
|
end
|
|
65
67
|
|
|
66
68
|
def trait(trait_name)
|
|
67
|
-
unless
|
|
69
|
+
unless api_definition.traits.has_key? trait_name
|
|
68
70
|
raise Exceptions::InvalidTrait.new("Trait #{trait_name} not found in the system")
|
|
69
71
|
end
|
|
70
72
|
|
|
71
|
-
trait =
|
|
73
|
+
trait = api_definition.traits.fetch(trait_name)
|
|
72
74
|
trait.apply!(self)
|
|
73
75
|
traits << trait_name
|
|
74
76
|
end
|
|
@@ -90,7 +92,7 @@ module Praxis
|
|
|
90
92
|
args[:media_type] = type
|
|
91
93
|
end
|
|
92
94
|
|
|
93
|
-
template =
|
|
95
|
+
template = api_definition.response(name)
|
|
94
96
|
@responses[name] = template.compile(self, **args)
|
|
95
97
|
end
|
|
96
98
|
|
|
@@ -303,7 +305,7 @@ module Praxis
|
|
|
303
305
|
|
|
304
306
|
# and return that one if it already corresponds to a registered handler
|
|
305
307
|
# otherwise, add the encoding
|
|
306
|
-
if
|
|
308
|
+
if resource_definition.application.handlers.include?(pick.handler_name)
|
|
307
309
|
return pick
|
|
308
310
|
else
|
|
309
311
|
return pick + handler_name
|
|
@@ -320,13 +322,13 @@ module Praxis
|
|
|
320
322
|
|
|
321
323
|
hash[:examples] = {}
|
|
322
324
|
|
|
323
|
-
default_handlers =
|
|
325
|
+
default_handlers = api_definition.info.consumes
|
|
324
326
|
|
|
325
327
|
default_handlers.each do |default_handler|
|
|
326
328
|
dumped_payload = payload.dump(example, default_format: default_handler)
|
|
327
329
|
|
|
328
330
|
content_type = derive_content_type(example, default_handler)
|
|
329
|
-
handler =
|
|
331
|
+
handler = resource_definition.application.handlers[content_type.handler_name]
|
|
330
332
|
|
|
331
333
|
# in case handler is nil, use dumped_payload as-is.
|
|
332
334
|
generated_payload = if handler.nil?
|
|
@@ -1,41 +1,57 @@
|
|
|
1
|
-
require 'singleton'
|
|
2
1
|
require 'forwardable'
|
|
3
2
|
|
|
4
3
|
module Praxis
|
|
5
4
|
|
|
6
5
|
class ApiDefinition
|
|
7
|
-
include Singleton
|
|
8
6
|
extend Forwardable
|
|
9
7
|
|
|
10
8
|
attr_reader :traits
|
|
11
9
|
attr_reader :responses
|
|
12
10
|
attr_reader :infos
|
|
13
11
|
attr_reader :global_info
|
|
12
|
+
attr_reader :application
|
|
14
13
|
|
|
15
14
|
attr_accessor :versioning_scheme
|
|
16
15
|
|
|
16
|
+
def self.instance
|
|
17
|
+
i = Thread.current[:praxis_instance] || $praxis_initializing_instance
|
|
18
|
+
raise "Trying to use Praxis::ApiDefinition outside the context of a Praxis::Application" unless i
|
|
19
|
+
i.api_definition
|
|
20
|
+
end
|
|
21
|
+
|
|
17
22
|
def self.define(&block)
|
|
23
|
+
|
|
24
|
+
definition = Praxis::Application.current_instance.api_definition
|
|
25
|
+
if block.arity == 0
|
|
26
|
+
definition.instance_eval(&block)
|
|
27
|
+
else
|
|
28
|
+
yield(definition)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def define(&block)
|
|
18
33
|
if block.arity == 0
|
|
19
|
-
self.
|
|
34
|
+
self.instance_eval(&block)
|
|
20
35
|
else
|
|
21
|
-
yield(self
|
|
36
|
+
yield(self)
|
|
22
37
|
end
|
|
23
38
|
end
|
|
24
39
|
|
|
25
|
-
def initialize
|
|
40
|
+
def initialize(application)
|
|
41
|
+
@application = application
|
|
26
42
|
@responses = Hash.new
|
|
27
43
|
@traits = Hash.new
|
|
28
44
|
@base_path = ''
|
|
29
45
|
|
|
30
|
-
@global_info = ApiGeneralInfo.new
|
|
46
|
+
@global_info = ApiGeneralInfo.new(application: application)
|
|
31
47
|
|
|
32
48
|
@infos = Hash.new do |hash, version|
|
|
33
|
-
hash[version] = ApiGeneralInfo.new(@global_info, version: version)
|
|
49
|
+
hash[version] = ApiGeneralInfo.new(@global_info, application: application, version: version)
|
|
34
50
|
end
|
|
35
51
|
end
|
|
36
52
|
|
|
37
53
|
def response_template(name, &block)
|
|
38
|
-
@responses[name] = Praxis::ResponseTemplate.new(name, &block)
|
|
54
|
+
@responses[name] = Praxis::ResponseTemplate.new(name, application, &block)
|
|
39
55
|
end
|
|
40
56
|
|
|
41
57
|
def response(name)
|
|
@@ -91,25 +107,26 @@ module Praxis
|
|
|
91
107
|
data
|
|
92
108
|
end
|
|
93
109
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
end
|
|
110
|
+
# CANNOT DEFINE IT AT FILE LOADING TIME: THE INSTANCE FOR THE API_DEFINITION IS NOT READY YET.
|
|
111
|
+
# define do |api|
|
|
112
|
+
# api.response_template :ok do |media_type: , location: nil, headers: nil, description: nil |
|
|
113
|
+
# status 200
|
|
114
|
+
# description( description || 'Standard response for successful HTTP requests.' )
|
|
115
|
+
#
|
|
116
|
+
# media_type media_type
|
|
117
|
+
# location location
|
|
118
|
+
# headers headers if headers
|
|
119
|
+
# end
|
|
120
|
+
#
|
|
121
|
+
# api.response_template :created do |media_type: nil, location: nil, headers: nil, description: nil|
|
|
122
|
+
# status 201
|
|
123
|
+
# description( description || 'The request has been fulfilled and resulted in a new resource being created.' )
|
|
124
|
+
#
|
|
125
|
+
# media_type media_type if media_type
|
|
126
|
+
# location location
|
|
127
|
+
# headers headers if headers
|
|
128
|
+
# end
|
|
129
|
+
# end
|
|
113
130
|
|
|
114
131
|
end
|
|
115
132
|
|
|
@@ -3,10 +3,11 @@ module Praxis
|
|
|
3
3
|
|
|
4
4
|
attr_reader :version
|
|
5
5
|
|
|
6
|
-
def initialize(global_info=nil, version: nil)
|
|
6
|
+
def initialize(global_info=nil, application:, version: nil)
|
|
7
7
|
@data = Hash.new
|
|
8
8
|
@global_info = global_info
|
|
9
9
|
@version = version
|
|
10
|
+
@application = application
|
|
10
11
|
|
|
11
12
|
if @global_info.nil? # this *is* the global info
|
|
12
13
|
version_with [:header, :params]
|
|
@@ -54,7 +55,7 @@ module Praxis
|
|
|
54
55
|
get(:version_with)
|
|
55
56
|
else
|
|
56
57
|
if @global_info.nil? # this *is* the global info
|
|
57
|
-
|
|
58
|
+
@application.versioning_scheme = val
|
|
58
59
|
set(:version_with, val)
|
|
59
60
|
else
|
|
60
61
|
raise "Use of version_with is only allowed in the global part of " \
|
data/lib/praxis/application.rb
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
require 'singleton'
|
|
2
1
|
require 'mustermann'
|
|
3
2
|
require 'logger'
|
|
4
3
|
|
|
5
4
|
module Praxis
|
|
6
5
|
class Application
|
|
7
|
-
include Singleton
|
|
8
6
|
|
|
9
7
|
attr_reader :router
|
|
10
8
|
attr_reader :controllers
|
|
11
9
|
attr_reader :resource_definitions
|
|
12
10
|
attr_reader :app
|
|
13
11
|
attr_reader :builder
|
|
12
|
+
attr_reader :api_definition
|
|
14
13
|
|
|
15
14
|
attr_accessor :bootloader
|
|
16
15
|
attr_accessor :file_layout
|
|
@@ -25,12 +24,30 @@ module Praxis
|
|
|
25
24
|
|
|
26
25
|
attr_accessor :versioning_scheme
|
|
27
26
|
|
|
27
|
+
@@registered_apps = {}
|
|
28
28
|
|
|
29
|
+
def self.registered_apps
|
|
30
|
+
@@registered_apps
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.instance
|
|
34
|
+
i = current_instance
|
|
35
|
+
return i if i
|
|
36
|
+
$praxis_initializing_instance = self.new
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.current_instance
|
|
40
|
+
Thread.current[:praxis_instance] || $praxis_initializing_instance
|
|
41
|
+
end
|
|
42
|
+
|
|
29
43
|
def self.configure
|
|
30
|
-
|
|
44
|
+
# Should fail (i.e., be nil) if it's not in initialization/setup or a runtime call
|
|
45
|
+
yield(current_instance)
|
|
31
46
|
end
|
|
32
47
|
|
|
33
|
-
def initialize
|
|
48
|
+
def initialize(name: 'default', skip_registration: false)
|
|
49
|
+
old = $praxis_initializing_instance
|
|
50
|
+
$praxis_initializing_instance = self # ApiDefinition.new needs to get the instance...
|
|
34
51
|
@controllers = Set.new
|
|
35
52
|
@resource_definitions = Set.new
|
|
36
53
|
|
|
@@ -51,37 +68,135 @@ module Praxis
|
|
|
51
68
|
@config = Config.new
|
|
52
69
|
@root = nil
|
|
53
70
|
@logger = Logger.new(STDOUT)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
71
|
+
@api_definition = ApiDefinition.new(self)
|
|
72
|
+
|
|
73
|
+
@api_definition.define do |api|
|
|
74
|
+
api.response_template :ok do |media_type: , location: nil, headers: nil, description: nil |
|
|
75
|
+
status 200
|
|
76
|
+
description( description || 'Standard response for successful HTTP requests.' )
|
|
77
|
+
|
|
78
|
+
media_type media_type
|
|
79
|
+
location location
|
|
80
|
+
headers headers if headers
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
api.response_template :created do |media_type: nil, location: nil, headers: nil, description: nil|
|
|
84
|
+
status 201
|
|
85
|
+
description( description || 'The request has been fulfilled and resulted in a new resource being created.' )
|
|
86
|
+
|
|
87
|
+
media_type media_type if media_type
|
|
88
|
+
location location
|
|
89
|
+
headers headers if headers
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
require 'praxis/responses/http'
|
|
94
|
+
self.api_definition.define do |api|
|
|
95
|
+
[
|
|
96
|
+
[ :accepted, 202, "The request has been accepted for processing, but the processing has not been completed." ],
|
|
97
|
+
[ :no_content, 204,"The server successfully processed the request, but is not returning any content."],
|
|
98
|
+
[ :multiple_choices, 300,"Indicates multiple options for the resource that the client may follow."],
|
|
99
|
+
[ :moved_permanently, 301,"This and all future requests should be directed to the given URI."],
|
|
100
|
+
[ :found, 302,"The requested resource resides temporarily under a different URI."],
|
|
101
|
+
[ :see_other, 303,"The response to the request can be found under another URI using a GET method"],
|
|
102
|
+
[ :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."],
|
|
103
|
+
[ :temporary_redirect, 307,"In this case, the request should be repeated with another URI; however, future requests should still use the original URI."],
|
|
104
|
+
[ :bad_request, 400,"The request cannot be fulfilled due to bad syntax."],
|
|
105
|
+
[ :unauthorized, 401,"Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided."],
|
|
106
|
+
[ :forbidden, 403,"The request was a valid request, but the server is refusing to respond to it."],
|
|
107
|
+
[ :not_found, 404,"The requested resource could not be found but may be available again in the future."],
|
|
108
|
+
[ :method_not_allowed, 405,"A request was made of a resource using a request method not supported by that resource."],
|
|
109
|
+
[ :not_acceptable, 406,"The requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request."],
|
|
110
|
+
[ :request_timeout, 408,"The server timed out waiting for the request."],
|
|
111
|
+
[ :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."],
|
|
112
|
+
[ :precondition_failed, 412,"The server does not meet one of the preconditions that the requester put on the request."],
|
|
113
|
+
[ :unprocessable_entity, 422,"The request was well-formed but was unable to be followed due to semantic errors."],
|
|
114
|
+
].each do |name, code, base_description|
|
|
115
|
+
api.response_template name do |media_type: nil, location: nil, headers: nil, description: nil|
|
|
116
|
+
status code
|
|
117
|
+
description( description || base_description ) # description can "potentially" be overriden in an individual action.
|
|
118
|
+
|
|
119
|
+
media_type media_type if media_type
|
|
120
|
+
location location if location
|
|
121
|
+
headers headers if headers
|
|
122
|
+
end
|
|
123
|
+
end
|
|
61
124
|
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
require 'praxis/responses/internal_server_error'
|
|
128
|
+
self.api_definition.define do |api|
|
|
129
|
+
api.response_template :internal_server_error do
|
|
130
|
+
description "A generic error message, given when an unexpected condition was encountered and no more specific message is suitable."
|
|
131
|
+
status 500
|
|
132
|
+
media_type "application/json"
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
require 'praxis/responses/validation_error'
|
|
137
|
+
self.api_definition.define do |api|
|
|
138
|
+
api.response_template :validation_error do
|
|
139
|
+
description "An error message indicating that one or more elements of the request did not match the API specification for the action"
|
|
140
|
+
status 400
|
|
141
|
+
media_type "application/json"
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
require 'praxis/responses/multipart_ok'
|
|
147
|
+
self.api_definition.define do |api|
|
|
148
|
+
api.response_template :multipart_ok do |media_type: Praxis::Types::MultipartArray|
|
|
149
|
+
status 200
|
|
150
|
+
media_type media_type
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
62
154
|
builtin_handlers = {
|
|
63
155
|
'plain' => Praxis::Handlers::Plain,
|
|
64
156
|
'json' => Praxis::Handlers::JSON,
|
|
65
157
|
'x-www-form-urlencoded' => Praxis::Handlers::WWWForm
|
|
66
158
|
}
|
|
159
|
+
|
|
67
160
|
# Register built-in handlers unless the app already provided its own
|
|
68
161
|
builtin_handlers.each_pair do |name, handler|
|
|
69
162
|
self.handler(name, handler) unless handlers.key?(name)
|
|
70
163
|
end
|
|
164
|
+
|
|
165
|
+
setup_initial_config!
|
|
166
|
+
|
|
167
|
+
unless skip_registration
|
|
168
|
+
if self.class.registered_apps[name]
|
|
169
|
+
raise "A Praxis instance named #{name} has already been registered, please use the :name parameter to initialize them"
|
|
170
|
+
end
|
|
171
|
+
self.class.registered_apps[name] = self
|
|
172
|
+
end
|
|
173
|
+
$praxis_initializing_instance = old
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def setup_initial_config!
|
|
177
|
+
self.config do
|
|
178
|
+
attribute :praxis do
|
|
179
|
+
attribute :validate_responses, Attributor::Boolean, default: false
|
|
180
|
+
attribute :validate_response_bodies, Attributor::Boolean, default: false
|
|
71
181
|
|
|
72
|
-
|
|
182
|
+
attribute :show_exceptions, Attributor::Boolean, default: false
|
|
183
|
+
attribute :x_cascade, Attributor::Boolean, default: true
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
73
187
|
|
|
74
|
-
@builder.run(@router)
|
|
75
|
-
@app = @builder.to_app
|
|
76
188
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
189
|
+
def setup(root: '.')
|
|
190
|
+
return self unless @app.nil?
|
|
191
|
+
saved_value = $praxis_initializing_instance
|
|
192
|
+
$praxis_initializing_instance = self
|
|
193
|
+
@root = Pathname.new(root).expand_path
|
|
80
194
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
195
|
+
bootloader.setup!
|
|
196
|
+
builder.run(@router)
|
|
197
|
+
@app = builder.to_app
|
|
84
198
|
|
|
199
|
+
$praxis_initializing_instance = saved_value
|
|
85
200
|
self
|
|
86
201
|
end
|
|
87
202
|
|
|
@@ -111,9 +226,13 @@ module Praxis
|
|
|
111
226
|
|
|
112
227
|
def call(env)
|
|
113
228
|
response = []
|
|
229
|
+
old = Thread.current[:praxis_instance]
|
|
230
|
+
Thread.current[:praxis_instance] = self
|
|
114
231
|
Notifications.instrument 'rack.request.all'.freeze, response: response do
|
|
115
232
|
response.push(*@app.call(env))
|
|
116
233
|
end
|
|
234
|
+
ensure
|
|
235
|
+
Thread.current[:praxis_instance] = old
|
|
117
236
|
end
|
|
118
237
|
|
|
119
238
|
def layout(&block)
|
data/lib/praxis/bootloader.rb
CHANGED
|
@@ -49,7 +49,7 @@ module Praxis
|
|
|
49
49
|
after(:app) do
|
|
50
50
|
Praxis::Mapper.finalize!
|
|
51
51
|
Praxis::Blueprint.finalize!
|
|
52
|
-
Praxis::ResourceDefinition.finalize!
|
|
52
|
+
Praxis::ResourceDefinition.finalize!(application: self.application)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
end
|
|
@@ -112,10 +112,8 @@ module Praxis
|
|
|
112
112
|
end
|
|
113
113
|
|
|
114
114
|
def setup!
|
|
115
|
-
# use the
|
|
116
|
-
use Praxis::Stats
|
|
115
|
+
# use the Notifications plugin by default
|
|
117
116
|
use Praxis::Notifications
|
|
118
|
-
|
|
119
117
|
run
|
|
120
118
|
end
|
|
121
119
|
|
|
@@ -8,7 +8,6 @@ module Praxis
|
|
|
8
8
|
# 1) the environment.rb file - generic stuff for all environments
|
|
9
9
|
# 2) "Deployer.environment".rb - environment specific stuff
|
|
10
10
|
def execute
|
|
11
|
-
setup_initial_config!
|
|
12
11
|
|
|
13
12
|
env_file = application.root + "config/environment.rb"
|
|
14
13
|
require env_file if File.exists? env_file
|
|
@@ -37,18 +36,6 @@ module Praxis
|
|
|
37
36
|
end
|
|
38
37
|
end
|
|
39
38
|
|
|
40
|
-
# TODO: not really sure I like this here... but where else is better?
|
|
41
|
-
def setup_initial_config!
|
|
42
|
-
application.config do
|
|
43
|
-
attribute :praxis do
|
|
44
|
-
attribute :validate_responses, Attributor::Boolean, default: false
|
|
45
|
-
attribute :validate_response_bodies, Attributor::Boolean, default: false
|
|
46
|
-
|
|
47
|
-
attribute :show_exceptions, Attributor::Boolean, default: false
|
|
48
|
-
attribute :x_cascade, Attributor::Boolean, default: true
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
39
|
|
|
53
40
|
end
|
|
54
41
|
|