praxis 0.21 → 2.0.pre.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +8 -15
  3. data/CHANGELOG.md +328 -299
  4. data/CONTRIBUTING.md +4 -4
  5. data/README.md +11 -9
  6. data/lib/api_browser/app/js/directives/attribute_table.js +2 -1
  7. data/lib/api_browser/app/js/directives/conditional_requirements.js +13 -0
  8. data/lib/api_browser/app/js/directives/type_placeholder.js +10 -1
  9. data/lib/api_browser/app/js/factories/normalize_attributes.js +4 -2
  10. data/lib/api_browser/app/js/factories/template_for.js +5 -2
  11. data/lib/api_browser/app/js/filters/has_requirement.js +14 -0
  12. data/lib/api_browser/app/js/filters/tag_requirement.js +13 -0
  13. data/lib/api_browser/app/sass/praxis.scss +11 -0
  14. data/lib/api_browser/app/views/action.html +2 -2
  15. data/lib/api_browser/app/views/directives/attribute_description/member_options.html +2 -2
  16. data/lib/api_browser/app/views/directives/attribute_table.html +1 -1
  17. data/lib/api_browser/app/views/type.html +1 -1
  18. data/lib/api_browser/app/views/type/details.html +2 -2
  19. data/lib/api_browser/app/views/types/embedded/array.html +2 -0
  20. data/lib/api_browser/app/views/types/embedded/default.html +3 -1
  21. data/lib/api_browser/app/views/types/embedded/requirements.html +6 -0
  22. data/lib/api_browser/app/views/types/embedded/single_req.html +9 -0
  23. data/lib/api_browser/app/views/types/embedded/struct.html +14 -2
  24. data/lib/api_browser/app/views/types/standalone/array.html +1 -1
  25. data/lib/api_browser/app/views/types/standalone/struct.html +2 -1
  26. data/lib/api_browser/package.json +1 -1
  27. data/lib/praxis.rb +9 -3
  28. data/lib/praxis/action_definition.rb +1 -1
  29. data/lib/praxis/action_definition/headers_dsl_compiler.rb +1 -1
  30. data/lib/praxis/application.rb +1 -9
  31. data/lib/praxis/bootloader.rb +1 -4
  32. data/lib/praxis/config.rb +1 -1
  33. data/lib/praxis/dispatcher.rb +10 -6
  34. data/lib/praxis/docs/generator.rb +2 -1
  35. data/lib/praxis/extensions/attribute_filtering/active_record_filter_query_builder.rb +180 -0
  36. data/lib/praxis/extensions/attribute_filtering/filtering_params.rb +273 -0
  37. data/lib/praxis/extensions/attribute_filtering/sequel_filter_query_builder.rb +125 -0
  38. data/lib/praxis/extensions/field_selection.rb +1 -9
  39. data/lib/praxis/extensions/field_selection/active_record_query_selector.rb +51 -0
  40. data/lib/praxis/extensions/field_selection/sequel_query_selector.rb +61 -0
  41. data/lib/praxis/extensions/rails_compat.rb +2 -0
  42. data/lib/praxis/extensions/rails_compat/request_methods.rb +19 -0
  43. data/lib/praxis/handlers/xml.rb +1 -1
  44. data/lib/praxis/mapper/active_model_compat.rb +98 -0
  45. data/lib/praxis/mapper/resource.rb +242 -0
  46. data/lib/praxis/mapper/selector_generator.rb +149 -0
  47. data/lib/praxis/mapper/sequel_compat.rb +76 -0
  48. data/lib/praxis/media_type_identifier.rb +2 -1
  49. data/lib/praxis/middleware_app.rb +20 -2
  50. data/lib/praxis/multipart/parser.rb +14 -2
  51. data/lib/praxis/notifications.rb +1 -1
  52. data/lib/praxis/plugins/mapper_plugin.rb +64 -0
  53. data/lib/praxis/plugins/rails_plugin.rb +104 -0
  54. data/lib/praxis/request.rb +7 -1
  55. data/lib/praxis/request_superclassing.rb +11 -0
  56. data/lib/praxis/resource_definition.rb +5 -5
  57. data/lib/praxis/response.rb +1 -1
  58. data/lib/praxis/route.rb +1 -1
  59. data/lib/praxis/routing_config.rb +1 -1
  60. data/lib/praxis/trait.rb +1 -1
  61. data/lib/praxis/types/media_type_common.rb +2 -2
  62. data/lib/praxis/types/multipart.rb +1 -1
  63. data/lib/praxis/types/multipart_array.rb +2 -2
  64. data/lib/praxis/types/multipart_array/part_definition.rb +1 -1
  65. data/lib/praxis/version.rb +1 -1
  66. data/praxis.gemspec +14 -13
  67. data/spec/functional_spec.rb +4 -7
  68. data/spec/praxis/action_definition_spec.rb +1 -1
  69. data/spec/praxis/application_spec.rb +1 -1
  70. data/spec/praxis/collection_spec.rb +3 -2
  71. data/spec/praxis/config_spec.rb +2 -2
  72. data/spec/praxis/extensions/field_selection/active_record_query_selector_spec.rb +106 -0
  73. data/spec/praxis/extensions/field_selection/sequel_query_selector_spec.rb +147 -0
  74. data/spec/praxis/extensions/field_selection/support/spec_resources_active_model.rb +130 -0
  75. data/spec/praxis/extensions/field_selection/support/spec_resources_sequel.rb +106 -0
  76. data/spec/praxis/handlers/xml_spec.rb +2 -2
  77. data/spec/praxis/mapper/resource_spec.rb +169 -0
  78. data/spec/praxis/mapper/selector_generator_spec.rb +293 -0
  79. data/spec/praxis/media_type_spec.rb +0 -10
  80. data/spec/praxis/middleware_app_spec.rb +29 -9
  81. data/spec/praxis/request_stages/action_spec.rb +8 -1
  82. data/spec/praxis/response_definition_spec.rb +7 -4
  83. data/spec/praxis/response_spec.rb +1 -1
  84. data/spec/praxis/responses/internal_server_error_spec.rb +2 -2
  85. data/spec/praxis/responses/validation_error_spec.rb +2 -2
  86. data/spec/praxis/router_spec.rb +1 -1
  87. data/spec/spec_app/app/controllers/instances.rb +1 -1
  88. data/spec/spec_app/config/environment.rb +3 -21
  89. data/spec/spec_helper.rb +11 -15
  90. data/spec/support/be_deep_equal_matcher.rb +39 -0
  91. data/spec/support/spec_resources.rb +124 -0
  92. data/tasks/thor/templates/generator/empty_app/Gemfile +3 -3
  93. metadata +102 -77
  94. data/.ruby-version +0 -1
  95. data/lib/praxis/extensions/mapper_selectors.rb +0 -16
  96. data/lib/praxis/media_type_collection.rb +0 -127
  97. data/lib/praxis/plugins/praxis_mapper_plugin.rb +0 -246
  98. data/lib/praxis/stats.rb +0 -113
  99. data/spec/praxis/media_type_collection_spec.rb +0 -157
  100. data/spec/praxis/plugins/praxis_mapper_plugin_spec.rb +0 -142
  101. data/spec/praxis/stats_spec.rb +0 -9
  102. data/spec/spec_app/app/models/person.rb +0 -3
@@ -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/rightscale/praxis/issues) on GitHub,
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/rightscale/praxis).
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/rightscale/praxis/issues) before anybody starts
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] [![Dependency Status][gemnasium-img-url]][gemnasium-url]
1
+ # Praxis [![TravisCI][travis-img-url]][travis-ci-url] [![Coverage Status][coveralls-img-url]][coveralls-url]
2
2
 
3
- [travis-img-url]: https://travis-ci.org/rightscale/praxis.svg?branch=master
4
- [travis-ci-url]:https://travis-ci.org/rightscale/praxis
5
- [coveralls-img-url]:https://coveralls.io/repos/rightscale/praxis/badge.svg?branch=master&service=github
6
- [coveralls-url]:https://coveralls.io/github/rightscale/praxis?branch=master
7
- [gemnasium-img-url]:https://gemnasium.com/rightscale/praxis.svg
8
- [gemnasium-url]:https://gemnasium.com/rightscale/praxis
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/rightscale/praxis-example-app) which showcases a few of the main design and implementation aspects that Praxis has to offer.
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/rightscale/praxis/blob/master/CONTRIBUTING.md)
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 (attribute.type && attribute.type.attributes) {
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 class="well">
3
- <attribute-description attribute="{options: row.value, description: 'These settings apply to the contained type:'}"></attribute-description>
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 ng-bind-html="name | attributeName">
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 ng-include="'views/types/embedded/default.html'" no-container></tr>
2
- <tr type-placeholder ng-repeat="(k,v) in type.attributes" type="v.type" template="embedded" name="name + '.' + k" details="v"></tr>
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="true"></attribute-table>
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/rightscale/praxis",
5
+ "repository": "https://github.com/praxis/praxis",
6
6
  "private": true,
7
7
  "scripts": {
8
8
  "test": "node_modules/.bin/grunt ci"
@@ -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'
@@ -76,7 +76,7 @@ module Praxis
76
76
 
77
77
  def update_attribute(attribute, options, block)
78
78
  attribute.options.merge!(options)
79
- attribute.type.attributes(options, &block)
79
+ attribute.type.attributes(**options, &block)
80
80
  end
81
81
 
82
82
  def response(name, type=nil, **args, &block)
@@ -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)
@@ -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
@@ -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 Stats and Notifications plugins by default
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
 
@@ -54,7 +54,7 @@ module Praxis
54
54
  )
55
55
  end
56
56
  top.options.merge!(opts)
57
- top.type.attributes(opts, &block)
57
+ top.type.attributes(**opts, &block)
58
58
  else
59
59
  @attribute.attributes[key] = Attributor::Attribute.new(type, opts, &block)
60
60
  end