praxis 0.21 → 2.0.pre.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +8 -15
- data/CHANGELOG.md +328 -299
- 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 +9 -3
- data/lib/praxis/action_definition.rb +1 -1
- data/lib/praxis/action_definition/headers_dsl_compiler.rb +1 -1
- data/lib/praxis/application.rb +1 -9
- data/lib/praxis/bootloader.rb +1 -4
- data/lib/praxis/config.rb +1 -1
- data/lib/praxis/dispatcher.rb +10 -6
- data/lib/praxis/docs/generator.rb +2 -1
- 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/sequel_filter_query_builder.rb +125 -0
- data/lib/praxis/extensions/field_selection.rb +1 -9
- data/lib/praxis/extensions/field_selection/active_record_query_selector.rb +51 -0
- data/lib/praxis/extensions/field_selection/sequel_query_selector.rb +61 -0
- data/lib/praxis/extensions/rails_compat.rb +2 -0
- data/lib/praxis/extensions/rails_compat/request_methods.rb +19 -0
- data/lib/praxis/handlers/xml.rb +1 -1
- data/lib/praxis/mapper/active_model_compat.rb +98 -0
- data/lib/praxis/mapper/resource.rb +242 -0
- data/lib/praxis/mapper/selector_generator.rb +149 -0
- data/lib/praxis/mapper/sequel_compat.rb +76 -0
- data/lib/praxis/media_type_identifier.rb +2 -1
- data/lib/praxis/middleware_app.rb +20 -2
- data/lib/praxis/multipart/parser.rb +14 -2
- data/lib/praxis/notifications.rb +1 -1
- data/lib/praxis/plugins/mapper_plugin.rb +64 -0
- data/lib/praxis/plugins/rails_plugin.rb +104 -0
- data/lib/praxis/request.rb +7 -1
- data/lib/praxis/request_superclassing.rb +11 -0
- data/lib/praxis/resource_definition.rb +5 -5
- data/lib/praxis/response.rb +1 -1
- data/lib/praxis/route.rb +1 -1
- data/lib/praxis/routing_config.rb +1 -1
- data/lib/praxis/trait.rb +1 -1
- data/lib/praxis/types/media_type_common.rb +2 -2
- data/lib/praxis/types/multipart.rb +1 -1
- data/lib/praxis/types/multipart_array.rb +2 -2
- data/lib/praxis/types/multipart_array/part_definition.rb +1 -1
- data/lib/praxis/version.rb +1 -1
- data/praxis.gemspec +14 -13
- data/spec/functional_spec.rb +4 -7
- data/spec/praxis/action_definition_spec.rb +1 -1
- data/spec/praxis/application_spec.rb +1 -1
- data/spec/praxis/collection_spec.rb +3 -2
- data/spec/praxis/config_spec.rb +2 -2
- data/spec/praxis/extensions/field_selection/active_record_query_selector_spec.rb +106 -0
- data/spec/praxis/extensions/field_selection/sequel_query_selector_spec.rb +147 -0
- data/spec/praxis/extensions/field_selection/support/spec_resources_active_model.rb +130 -0
- data/spec/praxis/extensions/field_selection/support/spec_resources_sequel.rb +106 -0
- data/spec/praxis/handlers/xml_spec.rb +2 -2
- data/spec/praxis/mapper/resource_spec.rb +169 -0
- data/spec/praxis/mapper/selector_generator_spec.rb +293 -0
- data/spec/praxis/media_type_spec.rb +0 -10
- data/spec/praxis/middleware_app_spec.rb +29 -9
- data/spec/praxis/request_stages/action_spec.rb +8 -1
- data/spec/praxis/response_definition_spec.rb +7 -4
- data/spec/praxis/response_spec.rb +1 -1
- data/spec/praxis/responses/internal_server_error_spec.rb +2 -2
- data/spec/praxis/responses/validation_error_spec.rb +2 -2
- data/spec/praxis/router_spec.rb +1 -1
- data/spec/spec_app/app/controllers/instances.rb +1 -1
- data/spec/spec_app/config/environment.rb +3 -21
- data/spec/spec_helper.rb +11 -15
- data/spec/support/be_deep_equal_matcher.rb +39 -0
- data/spec/support/spec_resources.rb +124 -0
- data/tasks/thor/templates/generator/empty_app/Gemfile +3 -3
- metadata +102 -77
- data/.ruby-version +0 -1
- data/lib/praxis/extensions/mapper_selectors.rb +0 -16
- data/lib/praxis/media_type_collection.rb +0 -127
- data/lib/praxis/plugins/praxis_mapper_plugin.rb +0 -246
- data/lib/praxis/stats.rb +0 -113
- data/spec/praxis/media_type_collection_spec.rb +0 -157
- data/spec/praxis/plugins/praxis_mapper_plugin_spec.rb +0 -142
- data/spec/praxis/stats_spec.rb +0 -9
- data/spec/spec_app/app/models/person.rb +0 -3
data/CONTRIBUTING.md
CHANGED
@@ -5,7 +5,7 @@ know if anything feels wrong or incomplete.
|
|
5
5
|
|
6
6
|
## Reporting Issues
|
7
7
|
|
8
|
-
When reporting [issues](https://github.com/
|
8
|
+
When reporting [issues](https://github.com/praxis/praxis/issues) on GitHub,
|
9
9
|
remember to include your Ruby version.
|
10
10
|
|
11
11
|
Please also include the steps required to reproduce the problem if possible and
|
@@ -45,8 +45,8 @@ everything for everybody. This means that we might decide against incorporating
|
|
45
45
|
a new feature. However, there might be a way to implement that feature *on top
|
46
46
|
of* Praxis.
|
47
47
|
|
48
|
-
If you want to work on something that we have already reviewed and prepared,
|
49
|
-
checkout the *Ready* column on our [Waffle board](https://waffle.io/
|
48
|
+
If you want to work on something that we have already reviewed and prepared,
|
49
|
+
checkout the *Ready* column on our [Waffle board](https://waffle.io/praxis/praxis).
|
50
50
|
|
51
51
|
### Discuss your design on the mailing list
|
52
52
|
|
@@ -60,7 +60,7 @@ is working on the same thing.
|
|
60
60
|
### Create issues...
|
61
61
|
|
62
62
|
Any significant improvement should be documented as [a GitHub
|
63
|
-
issue](https://github.com/
|
63
|
+
issue](https://github.com/praxis/praxis/issues) before anybody starts
|
64
64
|
working on it.
|
65
65
|
|
66
66
|
### ...but check for existing issues first!
|
data/README.md
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
-
# Praxis [![TravisCI][travis-img-url]][travis-ci-url] [![Coverage Status][coveralls-img-url]][coveralls-url]
|
1
|
+
# Praxis [![TravisCI][travis-img-url]][travis-ci-url] [![Coverage Status][coveralls-img-url]][coveralls-url]
|
2
2
|
|
3
|
-
[
|
4
|
-
|
5
|
-
[
|
6
|
-
[
|
7
|
-
[
|
8
|
-
[
|
3
|
+
[//]: # ( COMMENTED OUT UNTIL GEMNASIUM CAN SEE THE REPOS: [![Dependency Status][gemnasium-img-url]][gemnasium-url])
|
4
|
+
|
5
|
+
[travis-img-url]: https://travis-ci.org/praxis/praxis.svg?branch=master
|
6
|
+
[travis-ci-url]:https://travis-ci.org/praxis/praxis
|
7
|
+
[coveralls-img-url]:https://coveralls.io/repos/github/praxis/praxis/badge.svg?branch=master
|
8
|
+
[coveralls-url]:https://coveralls.io/github/praxis/praxis?branch=master
|
9
|
+
[gemnasium-img-url]:https://gemnasium.com/praxis/praxis.svg
|
10
|
+
[gemnasium-url]:https://gemnasium.com/praxis/praxis
|
9
11
|
|
10
12
|
Praxis is a framework for both _designing_ and _implementing_ APIs.
|
11
13
|
|
@@ -33,7 +35,7 @@ bundle
|
|
33
35
|
rackup
|
34
36
|
```
|
35
37
|
|
36
|
-
Or better yet, checkout a simple, but functional [blog example app](https://github.com/
|
38
|
+
Or better yet, checkout a simple, but functional [blog example app](https://github.com/praxis/praxis-example-app) which showcases a few of the main design and implementation aspects that Praxis has to offer.
|
37
39
|
|
38
40
|
|
39
41
|
## Mailing List
|
@@ -52,7 +54,7 @@ And follow us on twitter: [@praxisapi](http://twitter.com/praxisapi)
|
|
52
54
|
|
53
55
|
## Contributions
|
54
56
|
Contributions to make Praxis better are welcome. Please refer to
|
55
|
-
[CONTRIBUTING](https://github.com/
|
57
|
+
[CONTRIBUTING](https://github.com/praxis/praxis/blob/master/CONTRIBUTING.md)
|
56
58
|
for further details on what contributions are accepted and how to go about
|
57
59
|
contributing.
|
58
60
|
|
@@ -8,7 +8,8 @@ app.directive('attributeTable', function() {
|
|
8
8
|
templateUrl: 'views/directives/attribute_table.html',
|
9
9
|
scope: {
|
10
10
|
attributes: '=',
|
11
|
-
showGroups: '='
|
11
|
+
showGroups: '=',
|
12
|
+
parentRequirements: '='
|
12
13
|
},
|
13
14
|
link: function(scope) {
|
14
15
|
scope.groups = [{attributes: []}];
|
@@ -0,0 +1,13 @@
|
|
1
|
+
app.directive('conditionalRequirements', function() {
|
2
|
+
return {
|
3
|
+
restrict: 'E',
|
4
|
+
scope: {
|
5
|
+
requirements: '=',
|
6
|
+
},
|
7
|
+
templateUrl: 'views/types/embedded/requirements.html',
|
8
|
+
link: function(scope, element, attrs) {
|
9
|
+
// Reject requirements of type "all"
|
10
|
+
scope.condRequirements = _.reject(scope.requirements, {type: 'all'});
|
11
|
+
}
|
12
|
+
};
|
13
|
+
});
|
@@ -9,10 +9,19 @@ app.directive('typePlaceholder', function(templateFor, $stateParams) {
|
|
9
9
|
type: '=',
|
10
10
|
template: '@',
|
11
11
|
details: '=?',
|
12
|
-
name: '=?'
|
12
|
+
name: '=?',
|
13
|
+
parentRequirements: '=?',
|
13
14
|
},
|
14
15
|
link: function(scope, element) {
|
16
|
+
|
15
17
|
scope.apiVersion = $stateParams.version;
|
18
|
+
|
19
|
+
if( typeof scope.parentRequirements === 'undefined' ){
|
20
|
+
if( typeof scope.type.requirements !== 'undefined' && scope.type.requirements.length > 0 ){
|
21
|
+
scope.parentRequirements = scope.type.requirements;
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
16
25
|
templateFor(scope.type, scope.template).then(function(templateFn) {
|
17
26
|
element.replaceWith(templateFn(scope));
|
18
27
|
});
|
@@ -6,8 +6,10 @@ app.factory('normalizeAttributes', function() {
|
|
6
6
|
if (attribute.values != null) attribute.options.values = attribute.values;
|
7
7
|
if (attribute.default != null) attribute.options.default = attribute.default;
|
8
8
|
if (attribute.example != null) attribute.options.example = attribute.example;
|
9
|
-
if (
|
10
|
-
normalize(type, attribute.type.attributes, path);
|
9
|
+
if ( attribute.type.attributes ) {
|
10
|
+
normalize(attribute.type, attribute.type.attributes, path);
|
11
|
+
}else if( attribute.type.member_attribute ){
|
12
|
+
normalize(attribute.type.member_attribute.type, attribute.type.member_attribute.type.attributes, path);
|
11
13
|
}
|
12
14
|
});
|
13
15
|
}
|
@@ -56,6 +56,8 @@ app.provider('templateFor', function() {
|
|
56
56
|
switch ($family) {
|
57
57
|
case 'hash':
|
58
58
|
return 'views/types/embedded/struct.html';
|
59
|
+
case 'array':
|
60
|
+
return 'views/types/embedded/array.html';
|
59
61
|
default:
|
60
62
|
return 'views/types/embedded/default.html';
|
61
63
|
}
|
@@ -66,7 +68,7 @@ app.provider('templateFor', function() {
|
|
66
68
|
'ngInject';
|
67
69
|
if ($requestedTemplate === 'label') {
|
68
70
|
if ( $typeDefinition.member_attribute !== undefined) {
|
69
|
-
if ($typeDefinition.member_attribute.anonymous || _.contains(primitives, $typeDefinition.name)) {
|
71
|
+
if ($typeDefinition.member_attribute.anonymous || _.contains(primitives, $typeDefinition.member_attribute.type.name)) {
|
70
72
|
return 'views/types/label/primitive_collection.html';
|
71
73
|
} else{
|
72
74
|
return 'views/types/label/type_collection.html';
|
@@ -121,5 +123,6 @@ app.provider('templateFor', function() {
|
|
121
123
|
'Integer',
|
122
124
|
'Object',
|
123
125
|
'String',
|
124
|
-
'Struct'
|
126
|
+
'Struct',
|
127
|
+
'URI'
|
125
128
|
]);
|
@@ -0,0 +1,14 @@
|
|
1
|
+
app.filter('hasRequirement', function() {
|
2
|
+
return function(parent_reqs, attr_name) {
|
3
|
+
var name = _.last(attr_name.split('.'));
|
4
|
+
var groups=[]
|
5
|
+
if( parent_reqs.length > 0 ){
|
6
|
+
_.each(parent_reqs, function(reqdef) {
|
7
|
+
if( reqdef.attributes.includes(name) ){
|
8
|
+
groups.push(reqdef.type);
|
9
|
+
}
|
10
|
+
});
|
11
|
+
}
|
12
|
+
return groups;
|
13
|
+
};
|
14
|
+
});
|
@@ -0,0 +1,13 @@
|
|
1
|
+
app.filter('tagRequirement', function() {
|
2
|
+
return function(groups) {
|
3
|
+
if ( typeof groups === 'undefined' || groups.length == 0 ) {
|
4
|
+
return "";
|
5
|
+
}else if (groups.includes('all') ) {
|
6
|
+
var title = "required attribute";
|
7
|
+
return "<span class='required-attribute-mark' title=\""+title+"\" >*</span>"
|
8
|
+
} else {
|
9
|
+
var title = "conditionally required";
|
10
|
+
return"<span class='conditional-attribute-mark' title=\""+title+"\" >*</span>"
|
11
|
+
}
|
12
|
+
};
|
13
|
+
});
|
@@ -31,6 +31,17 @@
|
|
31
31
|
color: #aaa;
|
32
32
|
}
|
33
33
|
|
34
|
+
.required-attribute-mark {
|
35
|
+
color: red;
|
36
|
+
font-weight: bold;
|
37
|
+
}
|
38
|
+
|
39
|
+
.conditional-attribute-mark {
|
40
|
+
color: orange;
|
41
|
+
font-weight: bold;
|
42
|
+
}
|
43
|
+
|
44
|
+
|
34
45
|
.attribute-table {
|
35
46
|
div[class*='col-'] {
|
36
47
|
padding: $table-cell-padding;
|
@@ -26,14 +26,14 @@
|
|
26
26
|
<div class="row" ng-if="action.params.type.attributes">
|
27
27
|
<div class="col-lg-12">
|
28
28
|
<h2>Request Parameters</h2>
|
29
|
-
<type-placeholder details="action.params.type.attributes" type="action.params.type" template="standalone"></type-placeholder>
|
29
|
+
<type-placeholder details="action.params.type.attributes" type="action.params.type" template="standalone" parent-requirements="action.params.type.requirements"></type-placeholder>
|
30
30
|
</div>
|
31
31
|
</div>
|
32
32
|
|
33
33
|
<div class="row" ng-if="action.payload.type">
|
34
34
|
<div class="col-lg-12">
|
35
35
|
<h2>Request Body</h2>
|
36
|
-
<type-placeholder type="action.payload.type" template="standalone" details="action.payload.type.attributes"></type-placeholder>
|
36
|
+
<type-placeholder type="action.payload.type" template="standalone" details="action.payload.type.attributes" parent-requirements="action.payload.type.requirements"></type-placeholder>
|
37
37
|
</div>
|
38
38
|
</div>
|
39
39
|
|
@@ -1,4 +1,4 @@
|
|
1
1
|
<dt>Member type values</dt>
|
2
|
-
<dd
|
3
|
-
<attribute-description attribute="{options: row.value, description: 'These settings apply to the
|
2
|
+
<dd>
|
3
|
+
<attribute-description attribute="{options: row.value, description: '<em>These settings apply to each element of the collection:</em>'}"></attribute-description>
|
4
4
|
</dd>
|
@@ -11,7 +11,7 @@
|
|
11
11
|
<tr ng-if="g.name && g.attributes.length">
|
12
12
|
<th colspan="3">{{g.name}}</th>
|
13
13
|
</tr>
|
14
|
-
<tr type-placeholder ng-repeat="item in g.attributes" type="item.type" template="embedded" name="item.name" details="item"></tr>
|
14
|
+
<tr type-placeholder ng-repeat="item in g.attributes" type="item.type" template="embedded" name="item.name" details="item" parent-requirements="parentRequirements"></tr>
|
15
15
|
</tbody>
|
16
16
|
</table>
|
17
17
|
</div>
|
@@ -2,5 +2,5 @@
|
|
2
2
|
<div ng-if="error" class="alert alert-danger">
|
3
3
|
<p>The requested type could not be found.</p>
|
4
4
|
</div>
|
5
|
-
<type-placeholder type="type" template="main" details="type.attributes"></type-placeholder>
|
5
|
+
<type-placeholder type="type" template="main" details="type.attributes" parent-requirements="type.requirements"></type-placeholder>
|
6
6
|
</div>
|
@@ -5,9 +5,9 @@
|
|
5
5
|
<p ng-if="type.identifier"><b>Media-type identifier: {{ type.identifier }}</b></p>
|
6
6
|
<div ng-if="type.description" ng-bind-html="type.description | markdown"></div>
|
7
7
|
|
8
|
-
<attribute-table attributes="type.attributes"></attribute-table>
|
8
|
+
<attribute-table attributes="type.attributes" parent-requirements="type.requirements"></attribute-table>
|
9
9
|
</div>
|
10
|
-
<div ng-if="type.attributes === undefined" type-placeholder type="type" template="standalone" name="type.name" details="type"></div>
|
10
|
+
<div ng-if="type.attributes === undefined" type-placeholder type="type" template="standalone" name="type.name" details="type" parent-requirements="type.requirements"></div>
|
11
11
|
</div>
|
12
12
|
</div>
|
13
13
|
<div class="row" ng-if="views.length">
|
@@ -0,0 +1,2 @@
|
|
1
|
+
<tr ng-include="'views/types/embedded/default.html'" no-container parent-requirements="type.member_attributes.type.requirements"></tr>
|
2
|
+
<tr type-placeholder ng-repeat="(k,v) in type.member_attribute.type.attributes" type="v.type" template="embedded" name="'[].'+ name + '.' + k" details="v" parent-requirements="type.member_attributes.type.requirements"></tr>
|
@@ -1,8 +1,10 @@
|
|
1
1
|
<tr>
|
2
|
-
<td
|
2
|
+
<td>
|
3
|
+
<span ng-bind-html="name | attributeName"></span>
|
3
4
|
</td>
|
4
5
|
<td>
|
5
6
|
<type-placeholder template="label" type="type"></type-placeholder>
|
7
|
+
<span ng-bind-html="parentRequirements| hasRequirement:name | tagRequirement"></span>
|
6
8
|
</td>
|
7
9
|
<td>
|
8
10
|
<attribute-description attribute="details"></attribute-description>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<div ng-if="condRequirements.length > 0">
|
2
|
+
<p style='text-indent: 20px;margin-bottom: 0px'><em>its attributes must satisfy the following conditions:</em></p>
|
3
|
+
<ul>
|
4
|
+
<li ng-repeat="req in condRequirements" ng-include="'views/types/embedded/single_req.html'"></li>
|
5
|
+
</ul>
|
6
|
+
</div>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<p style='margin-bottom: 0px' ng-if="req.type == 'most'">
|
2
|
+
<em>at most {{req.count}} of:</em> <span ng-bind-html="req.attributes.join(', ')"></span>
|
3
|
+
</p>
|
4
|
+
<p style='margin-bottom: 0px' ng-if="req.type == 'least'">
|
5
|
+
<em>at least {{req.count}} of:</em> <span ng-bind-html="req.attributes.join(', ')"></span>
|
6
|
+
</p>
|
7
|
+
<p style='margin-bottom: 0px' ng-if="req.type == 'exactly'">
|
8
|
+
<em>exactly {{req.count}} of:</em> <span ng-bind-html="req.attributes.join(', ')"></span>
|
9
|
+
</p>
|
@@ -1,2 +1,14 @@
|
|
1
|
-
<tr
|
2
|
-
<
|
1
|
+
<tr>
|
2
|
+
<td>
|
3
|
+
<span ng-bind-html="name | attributeName"></span>
|
4
|
+
<conditional-requirements requirements='type.requirements'></conditional-requirements>
|
5
|
+
</td>
|
6
|
+
<td>
|
7
|
+
<type-placeholder template="label" type="type"></type-placeholder>
|
8
|
+
<span ng-bind-html="parentRequirements | hasRequirement:name | tagRequirement"></span>
|
9
|
+
</td>
|
10
|
+
<td>
|
11
|
+
<attribute-description attribute="details"></attribute-description>
|
12
|
+
</td>
|
13
|
+
</tr>
|
14
|
+
<tr type-placeholder ng-repeat="(k,v) in type.attributes" type="v.type" template="embedded" name="name + '.' + k" details="v" parent-requirements="type.requirements"></tr>
|
@@ -1,3 +1,3 @@
|
|
1
1
|
<p>A Collection of:</p>
|
2
2
|
|
3
|
-
<type-placeholder type="type.member_attribute.type" template="standalone" details="type.member_attribute.type.attributes"></type-placeholder>
|
3
|
+
<type-placeholder type="type.member_attribute.type" template="standalone" details="type.member_attribute.type.attributes" parent-requirements="type.member_attribute.type.requirements"></type-placeholder>
|
@@ -1 +1,2 @@
|
|
1
|
-
<attribute-table attributes="details" show-groups="
|
1
|
+
<attribute-table attributes="details" show-groups="false" parent-requirements="parentRequirements"></attribute-table>
|
2
|
+
<conditional-requirements requirements="parentRequirements "></conditional-requirements>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
"name": "api_doc_browser",
|
3
3
|
"version": "0.13.0",
|
4
4
|
"description": "Praxis API Browser app",
|
5
|
-
"repository": "https://github.com/
|
5
|
+
"repository": "https://github.com/praxis/praxis",
|
6
6
|
"private": true,
|
7
7
|
"scripts": {
|
8
8
|
"test": "node_modules/.bin/grunt ci"
|
data/lib/praxis.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'rack'
|
2
2
|
require 'attributor'
|
3
|
-
require 'praxis-mapper'
|
4
3
|
require 'praxis-blueprints'
|
5
4
|
|
6
5
|
require 'active_support/concern'
|
6
|
+
require 'praxis/request_superclassing'
|
7
|
+
require 'active_support/inflector'
|
7
8
|
|
8
9
|
$:.unshift File.dirname(__FILE__)
|
9
10
|
|
@@ -43,7 +44,6 @@ module Praxis
|
|
43
44
|
autoload :Stage, 'praxis/stage'
|
44
45
|
autoload :Trait, 'praxis/trait'
|
45
46
|
|
46
|
-
autoload :Stats, 'praxis/stats'
|
47
47
|
autoload :Notifications, 'praxis/notifications'
|
48
48
|
autoload :MiddlewareApp, 'praxis/middleware_app'
|
49
49
|
|
@@ -62,7 +62,6 @@ module Praxis
|
|
62
62
|
|
63
63
|
autoload :Links, 'praxis/links'
|
64
64
|
autoload :MediaType, 'praxis/media_type'
|
65
|
-
autoload :MediaTypeCollection, 'praxis/media_type_collection'
|
66
65
|
autoload :MediaTypeIdentifier, 'praxis/media_type_identifier'
|
67
66
|
autoload :Multipart, 'praxis/types/multipart'
|
68
67
|
autoload :Collection, 'praxis/collection'
|
@@ -89,6 +88,8 @@ module Praxis
|
|
89
88
|
autoload :MapperSelectors, 'praxis/extensions/mapper_selectors'
|
90
89
|
autoload :Rendering, 'praxis/extensions/rendering'
|
91
90
|
autoload :FieldExpansion, 'praxis/extensions/field_expansion'
|
91
|
+
autoload :ActiveRecordFilterQueryBuilder, 'praxis/extensions/attribute_filtering/active_record_filter_query_builder'
|
92
|
+
autoload :SequelFilterQueryBuilder, 'praxis/extensions/attribute_filtering/sequel_filter_query_builder'
|
92
93
|
end
|
93
94
|
|
94
95
|
module Handlers
|
@@ -122,6 +123,11 @@ module Praxis
|
|
122
123
|
autoload :Response, 'praxis/request_stages/response'
|
123
124
|
end
|
124
125
|
|
126
|
+
module Mapper
|
127
|
+
autoload :Resource, 'praxis/mapper/resource'
|
128
|
+
autoload :SelectorGenerator, 'praxis/mapper/selector_generator'
|
129
|
+
end
|
130
|
+
|
125
131
|
# Avoid loading responses (and templates) lazily as they need to be registered in time
|
126
132
|
require 'praxis/responses/http'
|
127
133
|
require 'praxis/responses/internal_server_error'
|
@@ -25,7 +25,7 @@ module Praxis
|
|
25
25
|
# Defining the existence without any other options can only mean that it is required (otherwise it is a useless definition)
|
26
26
|
options[:required] = true if options.empty?
|
27
27
|
end
|
28
|
-
key name , String, options
|
28
|
+
key name , String, **options
|
29
29
|
end
|
30
30
|
|
31
31
|
# Override the attribute to really call "key" in the hash (for temporary backwards compat)
|
data/lib/praxis/application.rb
CHANGED
@@ -74,14 +74,6 @@ module Praxis
|
|
74
74
|
@builder.run(@router)
|
75
75
|
@app = @builder.to_app
|
76
76
|
|
77
|
-
Notifications.subscribe 'rack.request.all'.freeze do |name, start, finish, _id, payload|
|
78
|
-
duration = (finish - start) * 1000
|
79
|
-
Stats.timing(name, duration)
|
80
|
-
|
81
|
-
status, _, _ = payload[:response]
|
82
|
-
Stats.increment "rack.request.#{status}"
|
83
|
-
end
|
84
|
-
|
85
77
|
self
|
86
78
|
end
|
87
79
|
|
@@ -122,7 +114,7 @@ module Praxis
|
|
122
114
|
|
123
115
|
def config(key=nil, type=Attributor::Struct, **opts, &block)
|
124
116
|
if block_given? || (type==Attributor::Struct && !opts.empty? )
|
125
|
-
@config.define(key, type, opts, &block)
|
117
|
+
@config.define(key, type, **opts, &block)
|
126
118
|
else
|
127
119
|
@config.get
|
128
120
|
end
|
data/lib/praxis/bootloader.rb
CHANGED
@@ -47,7 +47,6 @@ module Praxis
|
|
47
47
|
stages << BootloaderStages::WarnUnloadedFiles.new(:warn_unloaded_files, application)
|
48
48
|
|
49
49
|
after(:app) do
|
50
|
-
Praxis::Mapper.finalize!
|
51
50
|
Praxis::Blueprint.finalize!
|
52
51
|
Praxis::ResourceDefinition.finalize!
|
53
52
|
end
|
@@ -112,10 +111,8 @@ module Praxis
|
|
112
111
|
end
|
113
112
|
|
114
113
|
def setup!
|
115
|
-
# use the
|
116
|
-
use Praxis::Stats
|
114
|
+
# use the Notifications plugin by default
|
117
115
|
use Praxis::Notifications
|
118
|
-
|
119
116
|
run
|
120
117
|
end
|
121
118
|
|