praxis 0.21 → 2.0.pre.3
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/.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
|
|