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.
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