praxis 0.21 → 0.22.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +20 -12
  3. data/CHANGELOG.md +24 -0
  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 +8 -6
  28. data/lib/praxis/action_definition.rb +9 -7
  29. data/lib/praxis/api_definition.rb +44 -27
  30. data/lib/praxis/api_general_info.rb +3 -2
  31. data/lib/praxis/application.rb +139 -20
  32. data/lib/praxis/bootloader.rb +2 -4
  33. data/lib/praxis/bootloader_stages/environment.rb +0 -13
  34. data/lib/praxis/controller.rb +2 -0
  35. data/lib/praxis/dispatcher.rb +16 -10
  36. data/lib/praxis/docs/generator.rb +20 -9
  37. data/lib/praxis/docs/link_builder.rb +1 -1
  38. data/lib/praxis/error_handler.rb +5 -5
  39. data/lib/praxis/extensions/attribute_filtering.rb +28 -0
  40. data/lib/praxis/extensions/attribute_filtering/active_record_filter_query_builder.rb +180 -0
  41. data/lib/praxis/extensions/attribute_filtering/filtering_params.rb +273 -0
  42. data/lib/praxis/extensions/attribute_filtering/query_builder.rb +39 -0
  43. data/lib/praxis/extensions/field_selection.rb +3 -0
  44. data/lib/praxis/extensions/field_selection/active_record_query_selector.rb +57 -0
  45. data/lib/praxis/extensions/field_selection/sequel_query_selector.rb +65 -0
  46. data/lib/praxis/extensions/rails_compat.rb +2 -0
  47. data/lib/praxis/extensions/rails_compat/request_methods.rb +19 -0
  48. data/lib/praxis/extensions/rendering.rb +1 -1
  49. data/lib/praxis/file_group.rb +1 -1
  50. data/lib/praxis/middleware_app.rb +26 -6
  51. data/lib/praxis/multipart/parser.rb +14 -2
  52. data/lib/praxis/multipart/part.rb +5 -3
  53. data/lib/praxis/plugins/praxis_mapper_plugin.rb +2 -2
  54. data/lib/praxis/plugins/rails_plugin.rb +104 -0
  55. data/lib/praxis/request.rb +8 -9
  56. data/lib/praxis/request_stages/response.rb +3 -2
  57. data/lib/praxis/request_superclassing.rb +11 -0
  58. data/lib/praxis/resource_definition.rb +14 -10
  59. data/lib/praxis/response.rb +6 -7
  60. data/lib/praxis/response_definition.rb +7 -5
  61. data/lib/praxis/response_template.rb +4 -3
  62. data/lib/praxis/responses/http.rb +0 -36
  63. data/lib/praxis/responses/internal_server_error.rb +3 -12
  64. data/lib/praxis/responses/multipart_ok.rb +4 -11
  65. data/lib/praxis/responses/validation_error.rb +1 -10
  66. data/lib/praxis/router.rb +3 -3
  67. data/lib/praxis/tasks/api_docs.rb +10 -2
  68. data/lib/praxis/tasks/routes.rb +1 -0
  69. data/lib/praxis/version.rb +1 -1
  70. data/praxis.gemspec +4 -5
  71. data/spec/functional_spec.rb +4 -6
  72. data/spec/praxis/action_definition_spec.rb +26 -15
  73. data/spec/praxis/api_definition_spec.rb +13 -8
  74. data/spec/praxis/api_general_info_spec.rb +3 -8
  75. data/spec/praxis/application_spec.rb +13 -7
  76. data/spec/praxis/middleware_app_spec.rb +24 -10
  77. data/spec/praxis/request_spec.rb +17 -7
  78. data/spec/praxis/request_stages/validate_spec.rb +1 -1
  79. data/spec/praxis/resource_definition_spec.rb +12 -10
  80. data/spec/praxis/response_definition_spec.rb +22 -5
  81. data/spec/praxis/response_spec.rb +12 -5
  82. data/spec/praxis/responses/internal_server_error_spec.rb +4 -7
  83. data/spec/praxis/responses/validation_error_spec.rb +2 -2
  84. data/spec/praxis/router_spec.rb +8 -4
  85. data/spec/spec_app/config.ru +1 -6
  86. data/spec/spec_helper.rb +3 -3
  87. data/tasks/thor/templates/generator/empty_app/Gemfile +3 -3
  88. metadata +36 -32
  89. data/.ruby-version +0 -1
  90. data/lib/praxis/stats.rb +0 -113
  91. data/spec/praxis/stats_spec.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: d0a0928d3b9a59294d32767a333b73c03a0a7955
4
- data.tar.gz: 840261c0c55f18280f3c32d53a62053ed8582834
2
+ SHA256:
3
+ metadata.gz: c479acc3992139388b14120b7a76dde37e828ea034484786507f5a9b3fbb773f
4
+ data.tar.gz: 87a961f20eb8b758584306fa1082a72c79432ca897fa6c5d4b3716f251defa02
5
5
  SHA512:
6
- metadata.gz: 2c7d30737b31ec8204e030ca43577d8a4620b4a16ee3f9ec00c40ef740f08db8c7c21d9bc1d06dc7ddc56e2223dc0f9aaa990526a6f92f7297493dcf02158c11
7
- data.tar.gz: b1e794d55ef40a616c21adeb8a72cea53b796e4a943636c5a16a576f282298c6f573b730f708ab2a0bbb050784c56c3b1fe53f760488c3100d98958a2b50f6eb
6
+ metadata.gz: bcebeae7aa1dba132dbf3a28a9d14b359189f37a604817a7bba0ef1e4c1c9bffd9a89ab1bad553b6c4dbcccb53a362cc89ba1c3bdaf90f71adbf34f91e6d95ec
7
+ data.tar.gz: 4d5c5600fb77f9e26384640a2b562fba88a63151e34f6d277a521e51661b3212a62c7d5f92a372f4bef95cbae4f39372970e0b9ffc2c94d819f9441c54d7ea2a
data/.travis.yml CHANGED
@@ -2,19 +2,27 @@ language: ruby
2
2
  cache: bundler
3
3
  sudo: false
4
4
  rvm:
5
- - 2.2.5
6
- - 2.3.1
7
- node_js:
8
- - "0.10"
5
+ - 2.3
6
+ - 2.4
7
+ - 2.5
8
+ - 2.6
9
9
  branches:
10
10
  only:
11
11
  - master
12
12
  before_install:
13
- - cd lib/api_browser
14
- - npm install
15
- - cd ../..
16
- script:
17
- - bundle exec rspec spec
18
- - cd lib/api_browser
19
- - npm test
20
- - cd ../..
13
+ - gem update --system # Due to: https://github.com/travis-ci/travis-ci/issues/8978
14
+ # Leaving all API browser testing commented out as there are some very node dependencies that
15
+ # need to be worked out and updated
16
+ # node_js:
17
+ # - "0.10"
18
+ # before_install:
19
+ # - nvm install 0.10
20
+ # - node --version
21
+ # - cd lib/api_browser
22
+ # - npm install
23
+ # - cd ../..
24
+ # script:
25
+ # - bundle exec rspec spec
26
+ # - cd lib/api_browser
27
+ # - npm test
28
+ # - cd ../..
data/CHANGELOG.md CHANGED
@@ -2,6 +2,30 @@
2
2
 
3
3
  ## next
4
4
 
5
+ * Builds an initial Rails embeddability/compatibility set of functions and helpers:
6
+ * Refactored dispatcher methods so that instrumentation can be easily added on (but without building a flexible hook system that might decrease the performance)
7
+ * Change `Praxis:Request` super classing to be definable by a module setter
8
+ * Make `rails_compat/request_methods` to use it.
9
+ * Built `rails_compat` extension. Which for now only:
10
+ * changes `Praxis:Request` to derive from `ActionDispatch::Request`
11
+ * Will load the RailsPlugin code
12
+ * Built a `RailsPlugin` plugin which, for now, will:
13
+ * emulate firing off the `action_controller` basic hooks (`start_processing` and `process_action`).
14
+ * Add a few basic controller methods (which make some of the other mixing you might want to throw in your controllers happier). For example: the `head` method for controllers, as it is one of the most used for simple extensions. NOTE: The `render` method is not currently added.
15
+ * NOTE: db and view runtime values on request processing not done (i.e., not integrated with Praxis’ DB or rendering frameworks)
16
+ * Include URI in the primitive types when generating docs and displaying them (as to not have a generic URI schema polluting the lists)
17
+ * Loosen up the version of Rack that Praxis requires. Adapted the old MultipartParser to be compabible with Rack 2x (but in reality we should see about reusing the brand new parser that 2x comes with in the future)
18
+ * Loosen up the version of Mustermann to allow for their latest 1.x series (which will be used by some of the latest gems with Rails 5 and friends)
19
+ * Fix and improve Doc Browser presentation
20
+ * proper showing of substructures of payloads
21
+ * mark required attrs with red star (and semi-required as orange)
22
+ * display the existing special requirements as well
23
+ * Added requirements for parameters as well (in addition to payload)
24
+ * format member_options display better
25
+ * Make `MiddleWareApp` initialize lazily. This allows the main rack app (i.e., Rails) to be fully initialized by the time any code in the Praxis middleware gets touched (i.e., full ActiveRecord connection initialization...etc.)
26
+ * Removed 'Stats' plugin
27
+ * CGI.decode filter values in the `FilteringParams` extension
28
+
5
29
  ## 0.21
6
30
 
7
31
  * Protect against `MediaType`s that do not have any links defined.
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/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"
data/lib/praxis.rb CHANGED
@@ -4,6 +4,7 @@ require 'praxis-mapper'
4
4
  require 'praxis-blueprints'
5
5
 
6
6
  require 'active_support/concern'
7
+ require 'praxis/request_superclassing'
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
 
@@ -89,6 +89,7 @@ module Praxis
89
89
  autoload :MapperSelectors, 'praxis/extensions/mapper_selectors'
90
90
  autoload :Rendering, 'praxis/extensions/rendering'
91
91
  autoload :FieldExpansion, 'praxis/extensions/field_expansion'
92
+ autoload :AttributeFiltering, 'praxis/extensions/attribute_filtering'
92
93
  end
93
94
 
94
95
  module Handlers
@@ -122,10 +123,11 @@ module Praxis
122
123
  autoload :Response, 'praxis/request_stages/response'
123
124
  end
124
125
 
125
- # Avoid loading responses (and templates) lazily as they need to be registered in time
126
- require 'praxis/responses/http'
127
- require 'praxis/responses/internal_server_error'
128
- require 'praxis/responses/validation_error'
129
- require 'praxis/responses/multipart_ok'
126
+ # # Avoid loading responses (and templates) lazily as they need to be registered in time
127
+ # ... now done in Praxis initialize
128
+ # require 'praxis/responses/http'
129
+ # require 'praxis/responses/internal_server_error'
130
+ # require 'praxis/responses/validation_error'
131
+ # require 'praxis/responses/multipart_ok'
130
132
 
131
133
  end