praxis 0.16.1 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (399) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +0 -1
  3. data/.ruby-version +1 -1
  4. data/.travis.yml +2 -1
  5. data/CHANGELOG.md +41 -0
  6. data/CONTRIBUTING.md +3 -0
  7. data/lib/api_browser/Gruntfile.js +20 -4
  8. data/lib/api_browser/app/bower_components/angular-mocks/.bower.json +6 -6
  9. data/lib/api_browser/app/bower_components/angular-mocks/README.md +11 -5
  10. data/lib/api_browser/app/bower_components/angular-mocks/angular-mocks.js +475 -216
  11. data/lib/api_browser/app/bower_components/angular-mocks/bower.json +2 -2
  12. data/lib/api_browser/app/bower_components/angular-mocks/ngAnimateMock.js +2 -0
  13. data/lib/api_browser/app/bower_components/angular-mocks/ngMock.js +2 -0
  14. data/lib/api_browser/app/bower_components/angular-mocks/ngMockE2E.js +2 -0
  15. data/lib/api_browser/app/bower_components/angular-mocks/package.json +1 -1
  16. data/lib/api_browser/app/bower_components/angular-sanitize/.bower.json +8 -8
  17. data/lib/api_browser/app/bower_components/angular-sanitize/README.md +19 -5
  18. data/lib/api_browser/app/bower_components/angular-sanitize/angular-sanitize.js +186 -127
  19. data/lib/api_browser/app/bower_components/angular-sanitize/angular-sanitize.min.js +12 -10
  20. data/lib/api_browser/app/bower_components/angular-sanitize/angular-sanitize.min.js.map +3 -3
  21. data/lib/api_browser/app/bower_components/angular-sanitize/bower.json +3 -2
  22. data/lib/api_browser/app/bower_components/angular-sanitize/index.js +2 -0
  23. data/lib/api_browser/app/bower_components/angular-sanitize/package.json +26 -0
  24. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/.bower.json +15 -8
  25. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/bower.json +11 -3
  26. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap-csp.css +6 -0
  27. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap-tpls.js +1177 -453
  28. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap-tpls.min.js +4 -4
  29. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap.js +1066 -404
  30. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap.min.js +3 -3
  31. data/lib/api_browser/app/bower_components/angular-ui-router/.bower.json +5 -6
  32. data/lib/api_browser/app/bower_components/angular-ui-router/CHANGELOG.md +208 -3
  33. data/lib/api_browser/app/bower_components/angular-ui-router/CONTRIBUTING.md +65 -0
  34. data/lib/api_browser/app/bower_components/angular-ui-router/LICENSE +1 -1
  35. data/lib/api_browser/app/bower_components/angular-ui-router/README.md +36 -71
  36. data/lib/api_browser/app/bower_components/angular-ui-router/api/angular-ui-router.d.ts +126 -0
  37. data/lib/api_browser/app/bower_components/angular-ui-router/bower.json +1 -1
  38. data/lib/api_browser/app/bower_components/angular-ui-router/release/angular-ui-router.js +1902 -755
  39. data/lib/api_browser/app/bower_components/angular-ui-router/release/angular-ui-router.min.js +2 -2
  40. data/lib/api_browser/app/bower_components/angular-ui-router/src/common.js +69 -23
  41. data/lib/api_browser/app/bower_components/angular-ui-router/src/resolve.js +15 -5
  42. data/lib/api_browser/app/bower_components/angular-ui-router/src/state.js +556 -295
  43. data/lib/api_browser/app/bower_components/angular-ui-router/src/stateDirectives.js +101 -42
  44. data/lib/api_browser/app/bower_components/angular-ui-router/src/stateFilters.js +6 -2
  45. data/lib/api_browser/app/bower_components/angular-ui-router/src/templateFactory.js +2 -2
  46. data/lib/api_browser/app/bower_components/angular-ui-router/src/urlMatcherFactory.js +822 -97
  47. data/lib/api_browser/app/bower_components/angular-ui-router/src/urlRouter.js +274 -120
  48. data/lib/api_browser/app/bower_components/angular-ui-router/src/viewDirective.js +33 -20
  49. data/lib/api_browser/app/bower_components/angular-ui-router/src/viewScroll.js +1 -1
  50. data/lib/api_browser/app/bower_components/angular/.bower.json +5 -5
  51. data/lib/api_browser/app/bower_components/angular/README.md +2 -5
  52. data/lib/api_browser/app/bower_components/angular/angular-csp.css +5 -8
  53. data/lib/api_browser/app/bower_components/angular/angular.js +12975 -6996
  54. data/lib/api_browser/app/bower_components/angular/angular.min.js +285 -213
  55. data/lib/api_browser/app/bower_components/angular/angular.min.js.gzip +0 -0
  56. data/lib/api_browser/app/bower_components/angular/angular.min.js.map +3 -3
  57. data/lib/api_browser/app/bower_components/angular/bower.json +1 -1
  58. data/lib/api_browser/app/bower_components/angular/index.js +2 -0
  59. data/lib/api_browser/app/bower_components/angular/package.json +2 -2
  60. data/lib/api_browser/app/bower_components/bootstrap-sass/.bower.json +31 -16
  61. data/lib/api_browser/app/bower_components/bootstrap-sass/CHANGELOG.md +108 -0
  62. data/lib/api_browser/app/bower_components/bootstrap-sass/CONTRIBUTING.md +55 -37
  63. data/lib/api_browser/app/bower_components/bootstrap-sass/README.md +147 -206
  64. data/lib/api_browser/app/bower_components/bootstrap-sass/bower.json +19 -8
  65. data/lib/api_browser/app/bower_components/bootstrap-sass/{dist/fonts → vendor/assets/fonts/bootstrap}/glyphicons-halflings-regular.eot +0 -0
  66. data/lib/api_browser/app/bower_components/bootstrap-sass/{dist/fonts → vendor/assets/fonts/bootstrap}/glyphicons-halflings-regular.svg +0 -0
  67. data/lib/api_browser/app/bower_components/bootstrap-sass/{dist/fonts → vendor/assets/fonts/bootstrap}/glyphicons-halflings-regular.ttf +0 -0
  68. data/lib/api_browser/app/bower_components/bootstrap-sass/{dist/fonts → vendor/assets/fonts/bootstrap}/glyphicons-halflings-regular.woff +0 -0
  69. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/javascripts/bootstrap.js +12 -0
  70. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/affix.js +1 -1
  71. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/alert.js +1 -1
  72. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/button.js +11 -5
  73. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/carousel.js +5 -5
  74. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/collapse.js +1 -1
  75. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/dropdown.js +5 -5
  76. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/modal.js +1 -1
  77. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/popover.js +1 -1
  78. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/scrollspy.js +2 -2
  79. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/tab.js +1 -1
  80. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/tooltip.js +1 -1
  81. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/transition.js +1 -1
  82. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap.scss +1 -0
  83. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_alerts.scss +0 -0
  84. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_badges.scss +6 -6
  85. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_breadcrumbs.scss +0 -0
  86. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_button-groups.scss +7 -33
  87. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_buttons.scss +2 -5
  88. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_carousel.scss +1 -0
  89. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_close.scss +0 -0
  90. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_code.scss +0 -0
  91. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_component-animations.scss +0 -0
  92. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_dropdowns.scss +3 -8
  93. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_forms.scss +11 -0
  94. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_glyphicons.scss +5 -5
  95. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_grid.scss +12 -26
  96. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_input-groups.scss +1 -1
  97. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_jumbotron.scss +8 -2
  98. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_labels.scss +6 -0
  99. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_list-group.scss +0 -0
  100. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_media.scss +0 -0
  101. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_mixins.scss +38 -51
  102. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_modals.scss +2 -5
  103. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_navbar.scss +41 -53
  104. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_navs.scss +0 -20
  105. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_normalize.scss +0 -0
  106. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_pager.scss +0 -0
  107. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_pagination.scss +0 -0
  108. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_panels.scss +11 -1
  109. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_popovers.scss +0 -0
  110. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_print.scss +0 -0
  111. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_progress-bars.scss +0 -12
  112. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_responsive-utilities.scss +0 -0
  113. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_scaffolding.scss +0 -0
  114. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_tables.scss +5 -18
  115. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_theme.scss +2 -2
  116. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_thumbnails.scss +9 -3
  117. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_tooltip.scss +0 -0
  118. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_type.scss +54 -52
  119. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_utilities.scss +0 -0
  120. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_variables.scss +20 -11
  121. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_wells.scss +0 -0
  122. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/bootstrap.scss +0 -0
  123. data/lib/api_browser/app/bower_components/lodash/.bower.json +9 -13
  124. data/lib/api_browser/app/bower_components/lodash/LICENSE.txt +3 -3
  125. data/lib/api_browser/app/bower_components/lodash/bower.json +4 -7
  126. data/lib/api_browser/app/bower_components/lodash/lodash.js +12235 -0
  127. data/lib/api_browser/app/bower_components/lodash/lodash.min.js +98 -0
  128. data/lib/api_browser/app/index.html +0 -1
  129. data/lib/api_browser/app/js/app.js +2 -5
  130. data/lib/api_browser/app/js/controllers/action.js +21 -37
  131. data/lib/api_browser/app/js/controllers/controller.js +23 -1
  132. data/lib/api_browser/app/js/controllers/menu.js +46 -14
  133. data/lib/api_browser/app/js/controllers/type.js +2 -9
  134. data/lib/api_browser/app/js/directives/attribute_description.js +15 -5
  135. data/lib/api_browser/app/js/directives/attribute_table.js +6 -6
  136. data/lib/api_browser/app/js/directives/fixed_if_fits.js +20 -0
  137. data/lib/api_browser/app/js/directives/no_container.js +6 -6
  138. data/lib/api_browser/app/js/directives/type_placeholder.js +21 -0
  139. data/lib/api_browser/app/js/factories/Configuration.js +13 -0
  140. data/lib/api_browser/app/js/factories/Documentation.js +0 -3
  141. data/lib/api_browser/app/js/factories/normalize_attributes.js +19 -0
  142. data/lib/api_browser/app/js/factories/template_for.js +113 -0
  143. data/lib/api_browser/app/sass/modules/_body.scss +26 -4
  144. data/lib/api_browser/app/sass/modules/_sidebar.scss +68 -1
  145. data/lib/api_browser/app/sass/praxis.scss +1 -5
  146. data/lib/api_browser/app/sass/variables/_bootstrap-variables.scss +13 -4
  147. data/lib/api_browser/app/views/action.html +13 -17
  148. data/lib/api_browser/app/views/controller.html +32 -4
  149. data/lib/api_browser/app/views/directives/attribute_description.html +1 -1
  150. data/lib/api_browser/app/views/directives/attribute_description/{_default.html → default.html} +0 -0
  151. data/lib/api_browser/app/views/directives/attribute_description/example.html +13 -0
  152. data/lib/api_browser/app/views/directives/attribute_description/headers.html +8 -0
  153. data/lib/api_browser/app/views/directives/attribute_description/member_options.html +4 -0
  154. data/lib/api_browser/app/views/directives/attribute_description/values.html +14 -0
  155. data/lib/api_browser/app/views/directives/attribute_table.html +2 -2
  156. data/lib/api_browser/app/views/home.html +1 -3
  157. data/lib/api_browser/app/views/layout.html +3 -36
  158. data/lib/api_browser/app/views/menu.html +45 -0
  159. data/lib/api_browser/app/views/navbar.html +1 -1
  160. data/lib/api_browser/app/views/type.html +2 -2
  161. data/lib/api_browser/app/views/type/{_details.html → details.html} +6 -6
  162. data/lib/api_browser/app/views/types/embedded/default.html +10 -0
  163. data/lib/api_browser/app/views/types/embedded/links.html +11 -0
  164. data/lib/api_browser/app/views/types/embedded/struct.html +2 -0
  165. data/lib/api_browser/app/views/types/label/link.html +1 -0
  166. data/lib/api_browser/app/views/types/label/primitive.html +1 -0
  167. data/lib/api_browser/app/views/types/label/primitive_collection.html +1 -0
  168. data/lib/api_browser/app/views/types/label/type.html +1 -0
  169. data/lib/api_browser/app/views/types/label/type_collection.html +1 -0
  170. data/lib/api_browser/app/views/{directives/request_body/_default.html → types/standalone/default.html} +1 -1
  171. data/lib/api_browser/app/views/types/standalone/struct.html +1 -0
  172. data/lib/api_browser/bower.json +9 -9
  173. data/lib/api_browser/package.json +1 -1
  174. data/lib/praxis.rb +10 -4
  175. data/lib/praxis/action_definition.rb +16 -4
  176. data/lib/praxis/action_definition/headers_dsl_compiler.rb +5 -2
  177. data/lib/praxis/api_definition.rb +3 -1
  178. data/lib/praxis/api_general_info.rb +49 -5
  179. data/lib/praxis/application.rb +12 -4
  180. data/lib/praxis/bootloader.rb +1 -0
  181. data/lib/praxis/bootloader_stages/environment.rb +2 -0
  182. data/lib/praxis/bootloader_stages/routing.rb +1 -1
  183. data/lib/praxis/bootloader_stages/subgroup_loader.rb +1 -0
  184. data/lib/praxis/exceptions/validation.rb +7 -0
  185. data/lib/praxis/handlers/plain.rb +16 -0
  186. data/lib/praxis/handlers/xml.rb +4 -4
  187. data/lib/praxis/links.rb +13 -3
  188. data/lib/praxis/media_type_identifier.rb +3 -0
  189. data/lib/praxis/multipart/parser.rb +41 -48
  190. data/lib/praxis/multipart/part.rb +196 -3
  191. data/lib/praxis/request.rb +14 -11
  192. data/lib/praxis/request_stages/request_stage.rb +4 -0
  193. data/lib/praxis/request_stages/response.rb +10 -9
  194. data/lib/praxis/request_stages/validate.rb +1 -7
  195. data/lib/praxis/request_stages/validate_params_and_headers.rb +30 -5
  196. data/lib/praxis/request_stages/validate_payload.rb +14 -5
  197. data/lib/praxis/resource_definition.rb +117 -15
  198. data/lib/praxis/response.rb +6 -5
  199. data/lib/praxis/response_definition.rb +51 -5
  200. data/lib/praxis/responses/http.rb +5 -0
  201. data/lib/praxis/responses/multipart_ok.rb +51 -0
  202. data/lib/praxis/responses/validation_error.rb +7 -7
  203. data/lib/praxis/restful_doc_generator.rb +9 -4
  204. data/lib/praxis/route.rb +3 -2
  205. data/lib/praxis/router.rb +26 -16
  206. data/lib/praxis/router/rack.rb +51 -0
  207. data/lib/praxis/router/simple.rb +146 -0
  208. data/lib/praxis/routing_config.rb +2 -2
  209. data/lib/praxis/trait.rb +1 -1
  210. data/lib/praxis/types/fuzzy_hash.rb +49 -0
  211. data/lib/praxis/types/media_type_common.rb +1 -1
  212. data/lib/praxis/types/multipart.rb +47 -12
  213. data/lib/praxis/types/multipart_array.rb +320 -0
  214. data/lib/praxis/types/multipart_array/part_definition.rb +52 -0
  215. data/lib/praxis/validation_handler.rb +10 -0
  216. data/lib/praxis/version.rb +2 -2
  217. data/praxis.gemspec +3 -3
  218. data/spec/api_browser/directives/type_placeholder_spec.js +134 -0
  219. data/spec/api_browser/factories/normalize_attributes_spec.js +97 -0
  220. data/spec/api_browser/factories/template_for_spec.js +67 -0
  221. data/spec/functional_spec.rb +111 -45
  222. data/spec/praxis/action_definition_spec.rb +31 -7
  223. data/spec/praxis/api_definition_spec.rb +2 -2
  224. data/spec/praxis/api_general_info_spec.rb +25 -0
  225. data/spec/praxis/application_spec.rb +24 -11
  226. data/spec/praxis/handlers/xml_spec.rb +55 -33
  227. data/spec/praxis/links_spec.rb +18 -1
  228. data/spec/praxis/media_type_collection_spec.rb +1 -1
  229. data/spec/praxis/media_type_spec.rb +2 -2
  230. data/spec/praxis/multipart/parser_spec.rb +21 -13
  231. data/spec/praxis/plugins/praxis_mapper_plugin_spec.rb +1 -1
  232. data/spec/praxis/request_spec.rb +52 -24
  233. data/spec/praxis/{request_stages_action_spec.rb → request_stages/action_spec.rb} +1 -1
  234. data/spec/praxis/{request_stage_spec.rb → request_stages/request_stage_spec.rb} +0 -0
  235. data/spec/praxis/{request_stages_validate_spec.rb → request_stages/validate_spec.rb} +1 -1
  236. data/spec/praxis/resource_definition_spec.rb +30 -4
  237. data/spec/praxis/response_definition_spec.rb +60 -19
  238. data/spec/praxis/response_spec.rb +2 -2
  239. data/spec/praxis/responses/validation_error_spec.rb +33 -16
  240. data/spec/praxis/route_spec.rb +4 -2
  241. data/spec/praxis/router_spec.rb +28 -12
  242. data/spec/praxis/routing_config_spec.rb +11 -5
  243. data/spec/praxis/types/collection_spec.rb +1 -1
  244. data/spec/praxis/types/fuzzy_hash_spec.rb +20 -0
  245. data/spec/praxis/types/multipart_array/part_definition_spec.rb +5 -0
  246. data/spec/praxis/types/multipart_array_spec.rb +334 -0
  247. data/spec/praxis/types/multipart_spec.rb +14 -5
  248. data/spec/spec_app/app/controllers/instances.rb +20 -10
  249. data/spec/spec_app/app/controllers/volumes.rb +8 -4
  250. data/spec/spec_app/app/responses/bulk_response.rb +0 -6
  251. data/spec/spec_app/config/environment.rb +13 -0
  252. data/spec/spec_app/design/api.rb +7 -10
  253. data/spec/spec_app/design/media_types/instance.rb +3 -1
  254. data/spec/spec_app/design/resources/instances.rb +50 -41
  255. data/spec/spec_app/design/resources/volume_snapshots.rb +39 -0
  256. data/spec/spec_app/design/resources/volumes.rb +11 -6
  257. data/spec/spec_helper.rb +3 -1
  258. metadata +125 -218
  259. data/lib/api_browser/app/bower_components/angular-ui-router/src/compat.js +0 -146
  260. data/lib/api_browser/app/bower_components/bootstrap-sass/CNAME +0 -1
  261. data/lib/api_browser/app/bower_components/bootstrap-sass/DOCS-LICENSE +0 -319
  262. data/lib/api_browser/app/bower_components/bootstrap-sass/Gemfile +0 -5
  263. data/lib/api_browser/app/bower_components/bootstrap-sass/Gemfile.lock +0 -14
  264. data/lib/api_browser/app/bower_components/bootstrap-sass/Gruntfile.js +0 -244
  265. data/lib/api_browser/app/bower_components/bootstrap-sass/LICENSE +0 -176
  266. data/lib/api_browser/app/bower_components/bootstrap-sass/LICENSE-MIT +0 -21
  267. data/lib/api_browser/app/bower_components/bootstrap-sass/Rakefile +0 -44
  268. data/lib/api_browser/app/bower_components/bootstrap-sass/_config.yml +0 -25
  269. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/ads.html +0 -1
  270. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/footer.html +0 -34
  271. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/header.html +0 -42
  272. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-about.html +0 -12
  273. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-components.html +0 -137
  274. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-css.html +0 -99
  275. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-customize.html +0 -40
  276. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-getting-started.html +0 -44
  277. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-javascript.html +0 -88
  278. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-main.html +0 -37
  279. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/old-bs-docs.html +0 -8
  280. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/social-buttons.html +0 -16
  281. data/lib/api_browser/app/bower_components/bootstrap-sass/_layouts/default.html +0 -79
  282. data/lib/api_browser/app/bower_components/bootstrap-sass/_layouts/home.html +0 -47
  283. data/lib/api_browser/app/bower_components/bootstrap-sass/about.html +0 -93
  284. data/lib/api_browser/app/bower_components/bootstrap-sass/browserstack.json +0 -37
  285. data/lib/api_browser/app/bower_components/bootstrap-sass/components.html +0 -3689
  286. data/lib/api_browser/app/bower_components/bootstrap-sass/composer.json +0 -28
  287. data/lib/api_browser/app/bower_components/bootstrap-sass/css.html +0 -2674
  288. data/lib/api_browser/app/bower_components/bootstrap-sass/customize.html +0 -1715
  289. data/lib/api_browser/app/bower_components/bootstrap-sass/dist/css/bootstrap-theme.css +0 -427
  290. data/lib/api_browser/app/bower_components/bootstrap-sass/dist/css/bootstrap-theme.min.css +0 -1
  291. data/lib/api_browser/app/bower_components/bootstrap-sass/dist/css/bootstrap.css +0 -6350
  292. data/lib/api_browser/app/bower_components/bootstrap-sass/dist/css/bootstrap.min.css +0 -1
  293. data/lib/api_browser/app/bower_components/bootstrap-sass/dist/js/bootstrap.js +0 -2002
  294. data/lib/api_browser/app/bower_components/bootstrap-sass/dist/js/bootstrap.min.js +0 -9
  295. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/css/docs.css +0 -1195
  296. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/css/pygments-manni.css +0 -66
  297. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/ico/apple-touch-icon-144-precomposed.png +0 -0
  298. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/ico/favicon.png +0 -0
  299. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/application.js +0 -103
  300. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/customizer.js +0 -332
  301. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/filesaver.js +0 -169
  302. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/holder.js +0 -404
  303. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/ie8-responsive-file-warning.js +0 -12
  304. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/jszip.js +0 -1467
  305. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/less.js +0 -9
  306. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/raw-files.js +0 -3
  307. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/uglify.js +0 -14
  308. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/carousel/carousel.css +0 -148
  309. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/carousel/index.html +0 -206
  310. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/grid/grid.css +0 -28
  311. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/grid/index.html +0 -148
  312. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/jumbotron-narrow/index.html +0 -82
  313. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/jumbotron-narrow/jumbotron-narrow.css +0 -79
  314. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/jumbotron/index.html +0 -99
  315. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/jumbotron/jumbotron.css +0 -5
  316. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/justified-nav/index.html +0 -83
  317. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/justified-nav/justified-nav.css +0 -88
  318. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/navbar-fixed-top/index.html +0 -91
  319. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/navbar-fixed-top/navbar-fixed-top.css +0 -4
  320. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/navbar-static-top/index.html +0 -92
  321. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/navbar-static-top/navbar-static-top.css +0 -7
  322. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/navbar/index.html +0 -88
  323. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/navbar/navbar.css +0 -8
  324. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/non-responsive/index.html +0 -101
  325. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/non-responsive/non-responsive.css +0 -116
  326. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/offcanvas/index.html +0 -130
  327. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/offcanvas/offcanvas.css +0 -50
  328. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/offcanvas/offcanvas.js +0 -5
  329. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/carousel.jpg +0 -0
  330. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/grid.jpg +0 -0
  331. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/jumbotron-narrow.jpg +0 -0
  332. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/jumbotron.jpg +0 -0
  333. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/justified-nav.jpg +0 -0
  334. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/navbar-fixed.jpg +0 -0
  335. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/navbar-static.jpg +0 -0
  336. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/navbar.jpg +0 -0
  337. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/non-responsive.jpg +0 -0
  338. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/offcanvas.jpg +0 -0
  339. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/sign-in.jpg +0 -0
  340. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/starter-template.jpg +0 -0
  341. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/sticky-footer-navbar.jpg +0 -0
  342. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/sticky-footer.jpg +0 -0
  343. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/theme.jpg +0 -0
  344. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/signin/index.html +0 -50
  345. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/signin/signin.css +0 -40
  346. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/starter-template/index.html +0 -68
  347. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/starter-template/starter-template.css +0 -7
  348. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/sticky-footer-navbar/index.html +0 -91
  349. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/sticky-footer-navbar/sticky-footer-navbar.css +0 -45
  350. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/sticky-footer/index.html +0 -55
  351. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/sticky-footer/sticky-footer.css +0 -38
  352. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/theme/index.html +0 -384
  353. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/theme/theme.css +0 -14
  354. data/lib/api_browser/app/bower_components/bootstrap-sass/fonts/glyphicons-halflings-regular.eot +0 -0
  355. data/lib/api_browser/app/bower_components/bootstrap-sass/fonts/glyphicons-halflings-regular.svg +0 -229
  356. data/lib/api_browser/app/bower_components/bootstrap-sass/fonts/glyphicons-halflings-regular.ttf +0 -0
  357. data/lib/api_browser/app/bower_components/bootstrap-sass/fonts/glyphicons-halflings-regular.woff +0 -0
  358. data/lib/api_browser/app/bower_components/bootstrap-sass/getting-started.html +0 -1021
  359. data/lib/api_browser/app/bower_components/bootstrap-sass/index.html +0 -16
  360. data/lib/api_browser/app/bower_components/bootstrap-sass/javascript.html +0 -1983
  361. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/index.html +0 -52
  362. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/affix.js +0 -25
  363. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/alert.js +0 -62
  364. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/button.js +0 -116
  365. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/carousel.js +0 -87
  366. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/collapse.js +0 -164
  367. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/dropdown.js +0 -219
  368. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/modal.js +0 -196
  369. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/phantom.js +0 -69
  370. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/popover.js +0 -133
  371. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/scrollspy.js +0 -37
  372. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/tab.js +0 -86
  373. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/tooltip.js +0 -437
  374. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/transition.js +0 -13
  375. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/vendor/jquery.js +0 -6
  376. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/vendor/qunit.css +0 -232
  377. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/vendor/qunit.js +0 -1510
  378. data/lib/api_browser/app/bower_components/bootstrap-sass/package.json +0 -40
  379. data/lib/api_browser/app/bower_components/lodash/dist/lodash.compat.js +0 -7157
  380. data/lib/api_browser/app/bower_components/lodash/dist/lodash.compat.min.js +0 -61
  381. data/lib/api_browser/app/bower_components/lodash/dist/lodash.js +0 -6785
  382. data/lib/api_browser/app/bower_components/lodash/dist/lodash.min.js +0 -56
  383. data/lib/api_browser/app/bower_components/lodash/dist/lodash.underscore.js +0 -4979
  384. data/lib/api_browser/app/bower_components/lodash/dist/lodash.underscore.min.js +0 -39
  385. data/lib/api_browser/app/js/directives/attribute_table_row.js +0 -17
  386. data/lib/api_browser/app/js/directives/request_body.js +0 -25
  387. data/lib/api_browser/app/js/directives/request_headers.js +0 -17
  388. data/lib/api_browser/app/js/directives/request_parameters.js +0 -17
  389. data/lib/api_browser/app/js/directives/type_label.js +0 -52
  390. data/lib/api_browser/app/js/factories/PayloadTemplates.js +0 -10
  391. data/lib/api_browser/app/js/factories/TemplateProvider.js +0 -45
  392. data/lib/api_browser/app/js/factories/TypeTemplates.js +0 -11
  393. data/lib/api_browser/app/views/directives/attribute_description/_example.html +0 -13
  394. data/lib/api_browser/app/views/directives/attribute_description/_headers.html +0 -8
  395. data/lib/api_browser/app/views/directives/attribute_table_row/_default.html +0 -10
  396. data/lib/api_browser/app/views/directives/attribute_table_row/_links.html +0 -11
  397. data/lib/api_browser/app/views/directives/attribute_table_row/_struct.html +0 -2
  398. data/lib/api_browser/app/views/directives/request_body/_struct.html +0 -1
  399. data/lib/api_browser/app/views/resource/_actions.html +0 -27
@@ -55,6 +55,15 @@ module Praxis
55
55
  end
56
56
  end
57
57
 
58
+ def example(context=nil)
59
+ return nil if self.media_type.nil?
60
+ return nil if self.media_type.kind_of?(SimpleMediaType)
61
+ if context.nil?
62
+ context = "#{self.media_type.name}-#{self.name}"
63
+ end
64
+ self.media_type.example(context)
65
+ end
66
+
58
67
  def location(loc=nil)
59
68
  return @spec[:location] if loc.nil?
60
69
  unless ( loc.is_a?(Regexp) || loc.is_a?(String) )
@@ -120,6 +129,14 @@ module Praxis
120
129
  media_type.describe(true) # TODO: is a shallow describe what we want? or just the name?
121
130
  end
122
131
  end
132
+
133
+ # Generate an appropriate response example.
134
+ # A rendered response will need to contain not just the body of the associated media_type...
135
+ # but also headers, url...etc...
136
+ #if (media_type_example = self.example)
137
+ # content[:example] = self.media_type.dump( media_type_example )
138
+ #end
139
+
123
140
  unless headers == nil
124
141
  headers.each do |name, value|
125
142
  content[:headers][name] = _describe_header(value)
@@ -137,12 +154,16 @@ module Praxis
137
154
  { :value => data_value, :type => data_type }
138
155
  end
139
156
 
140
- def validate( response )
157
+ def validate(response, validate_body: false)
141
158
  validate_status!(response)
142
159
  validate_location!(response)
143
160
  validate_headers!(response)
144
161
  validate_content_type!(response)
145
162
  validate_parts!(response)
163
+
164
+ if validate_body
165
+ validate_body!(response)
166
+ end
146
167
  end
147
168
 
148
169
  def parts(proc=nil, like: nil, **args, &block)
@@ -227,7 +248,7 @@ module Praxis
227
248
 
228
249
  # Validates Content-Type header and response media type
229
250
  #
230
- # @param [Object] action
251
+ # @param [Object] response
231
252
  #
232
253
  # @raise [Exceptions::Validation] When there is a missing required header
233
254
  #
@@ -245,13 +266,38 @@ module Praxis
245
266
  end
246
267
  end
247
268
 
269
+ # Validates response body
270
+ #
271
+ # @param [Object] response
272
+ #
273
+ # @raise [Exceptions::Validation] When there is a missing required header..
274
+ def validate_body!(response)
275
+ return unless media_type
276
+ return if media_type.kind_of? SimpleMediaType
277
+
278
+ errors = self.media_type.validate(self.media_type.load(response.body))
279
+ if errors.any?
280
+ message = "Invalid response body for #{media_type.identifier}." +
281
+ "Errors: #{errors.inspect}"
282
+ raise Exceptions::Validation.new(message, errors: errors)
283
+ end
284
+
285
+ end
286
+
248
287
  def validate_parts!(response)
249
288
  return unless parts
250
289
 
251
- response.parts.each do |name, part|
252
- parts.validate(part)
290
+ case response.body
291
+ when Praxis::Types::MultipartArray
292
+ response.body.each do |part|
293
+ parts.validate(part)
294
+ end
295
+ else
296
+ # TODO: remove with other Multipart deprecations.
297
+ response.parts.each do |name, part|
298
+ parts.validate(part)
299
+ end
253
300
  end
254
-
255
301
  end
256
302
 
257
303
  end
@@ -18,6 +18,11 @@ module Praxis
18
18
  # being created.
19
19
  class Created < Praxis::Response
20
20
  self.status = 201
21
+
22
+ def initialize(status:self.class.status, headers:{}, body:'', location: nil)
23
+ super(status: status, headers: headers, body: body)
24
+ headers['Location'] = location if location
25
+ end
21
26
  end
22
27
 
23
28
 
@@ -0,0 +1,51 @@
1
+ module Praxis
2
+ module Responses
3
+ class MultipartOk < Ok
4
+
5
+ def initialize(status:self.class.status, headers:{}, body:'')
6
+ @name = response_name
7
+ @status = status
8
+ @headers = headers
9
+ @body = body
10
+ end
11
+
12
+ def handle
13
+ case @body
14
+ when Praxis::Types::MultipartArray
15
+ if @headers['Content-Type'].nil?
16
+ @headers['Content-Type'] = @body.content_type
17
+ end
18
+ end
19
+ end
20
+
21
+
22
+ def encode!
23
+ case @body
24
+ when Praxis::Types::MultipartArray
25
+ @body = @body.dump
26
+ else
27
+ super
28
+ end
29
+ end
30
+
31
+ def finish
32
+ format!
33
+ encode!
34
+
35
+ @body = Array(@body)
36
+
37
+ [@status, @headers, @body]
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
44
+ ApiDefinition.define do |api|
45
+ api.response_template :multipart_ok do |media_type: Praxis::Types::MultipartArray|
46
+ status 200
47
+ media_type media_type
48
+ end
49
+ end
50
+
51
+ end
@@ -3,20 +3,20 @@ module Praxis
3
3
  module Responses
4
4
 
5
5
  class ValidationError < BadRequest
6
- def initialize(errors: nil, exception: nil, message: nil, **opts)
6
+ def initialize(summary:, errors: nil, exception: nil, **opts)
7
7
  super(**opts)
8
8
  @headers['Content-Type'] = 'application/json' #TODO: might want an error mediatype
9
9
  @errors = errors
10
+ unless @errors # The exception message will the the only error if no errors are passed in
11
+ @errors = [exception.message] if exception && exception.message
12
+ end
10
13
  @exception = exception
11
- @message = message || (exception && exception.message)
14
+ @summary = summary
12
15
  end
13
16
 
14
17
  def format!
15
- if @errors
16
- @body = {name: 'ValidationError', errors: @errors}
17
- elsif @message
18
- @body = {name: 'ValidationError', message: @message}
19
- end
18
+ @body = {name: 'ValidationError', summary: @summary }
19
+ @body[:errors] = @errors if @errors
20
20
 
21
21
  if @exception && @exception.cause
22
22
  @body[:cause] = {name: @exception.cause.class.name, message: @exception.cause.message}
@@ -108,6 +108,10 @@ module Praxis
108
108
  end
109
109
  end
110
110
 
111
+ def parent
112
+ @controller_config.parent
113
+ end
114
+
111
115
  def friendly_name
112
116
  # FIXME: is it really about the controller? or the attached resource definition?
113
117
  segments = self.name.split("::")
@@ -160,7 +164,7 @@ module Praxis
160
164
  def dump_example_for(context_name, object)
161
165
  example = object.example(Array(context_name))
162
166
  if object.is_a? Praxis::Blueprint
163
- example.render(:master)
167
+ example.render(view: :master)
164
168
  elsif object.is_a? Attributor::Attribute
165
169
  object.dump(example)
166
170
  else
@@ -216,7 +220,7 @@ module Praxis
216
220
  type_output[:views].each do |view_name, view_info|
217
221
  # Add and example for each view
218
222
  unless( type < Praxis::Links ) #TODO: why do we need to skip an example for links?
219
- view_info[:example] = example_data.render(view_name)
223
+ view_info[:example] = example_data.render(view: view_name)
220
224
  end
221
225
  end
222
226
  end
@@ -224,7 +228,7 @@ module Praxis
224
228
  # ...but not for links or link classes (there's no object container context if done alone!!)
225
229
  unless( type < Praxis::Links ) #TODO: again, why is this special?
226
230
  type_output[:example] = if example_data.respond_to? :render
227
- example_data.render(:master)
231
+ example_data.render(view: :master)
228
232
  else
229
233
  type.dump(example_data)
230
234
  end
@@ -259,6 +263,7 @@ module Praxis
259
263
  @resources.each do |r|
260
264
  index[r.version] ||= Hash.new
261
265
  info = {controller: r.id, name: r.name}
266
+ info[:parent] = r.parent.controller ? r.parent.controller.id : r.parent.id if r.parent
262
267
  if r.media_type
263
268
  info[:media_type] = r.media_type.id
264
269
  media_types_seen_from_controllers << r.media_type
@@ -275,7 +280,7 @@ module Praxis
275
280
 
276
281
  reportable_types.each do |type|
277
282
  index[version] ||= Hash.new
278
- display_name = type.name.split("::").last + " (*)" #somehow this is just a MT so we probably wanna mark it different
283
+ display_name = type.name.split("::").last
279
284
  if index[version].has_key? display_name
280
285
  raise "Display name already taken for version #{version}! #{display_name}"
281
286
  end
data/lib/praxis/route.rb CHANGED
@@ -1,14 +1,15 @@
1
1
  module Praxis
2
2
 
3
3
  class Route
4
- attr_accessor :verb, :path, :version, :name, :options
4
+ attr_accessor :verb, :path, :version, :name, :prefixed_path, :options
5
5
 
6
- def initialize(verb, path, version='n/a', name:nil, **options)
6
+ def initialize(verb, path, version='n/a', name:nil, prefixed_path:nil, **options)
7
7
  @verb = verb
8
8
  @path = path
9
9
  @version = version
10
10
  @name = name
11
11
  @options = options
12
+ @prefixed_path = prefixed_path
12
13
  end
13
14
 
14
15
  def describe
data/lib/praxis/router.rb CHANGED
@@ -1,9 +1,11 @@
1
- require 'mustermann/router/rack'
1
+ require 'praxis/router/rack'
2
2
 
3
3
  module Praxis
4
4
 
5
5
  class Router
6
- attr_reader :request_class, :application
6
+ attr_reader :request_class
7
+ attr_reader :application
8
+
7
9
 
8
10
  class VersionMatcher
9
11
  def initialize(target, version: 'n/a')
@@ -11,7 +13,7 @@ module Praxis
11
13
  @version = version
12
14
  end
13
15
  def call(request)
14
- if request.version(@target.action.resource_definition.version_options) == @version
16
+ if request.version == @version
15
17
  @target.call(request)
16
18
  else
17
19
  # Version doesn't match, pass and continue
@@ -41,15 +43,23 @@ module Praxis
41
43
 
42
44
  def initialize(application, request_class: Praxis::Request)
43
45
  @routes = Hash.new do |hash, verb|
44
- hash[verb] = RequestRouter.new
46
+ hash[verb] = RequestRouter.new
45
47
  end
46
48
  @request_class = request_class
47
49
  @application = application
48
50
  end
49
51
 
50
52
  def add_route(target, route)
51
- version_wrapper = VersionMatcher.new(target, version: route.version)
52
- @routes[route.verb].on(route.path, call: version_wrapper)
53
+ path_versioning = (Application.instance.versioning_scheme == :path)
54
+
55
+ # DEPRECATED: remove with ResourceDefinition.version using: :path
56
+ path_versioning ||= (target.action.resource_definition.version_options[:using] == :path)
57
+
58
+ unless path_versioning
59
+ target = VersionMatcher.new(target, version: route.version)
60
+ end
61
+
62
+ @routes[route.verb].on(route.path, call: target)
53
63
  end
54
64
 
55
65
  def call(env_or_request)
@@ -67,26 +77,26 @@ module Praxis
67
77
  result = r.call(request) if r
68
78
  # If we didn't have an exact verb route, or if we did but the rest or route conditions didn't match
69
79
  if( r == nil || result == :not_found )
70
- # Fallback to a wildcard router, if there is one registered
80
+ # Fallback to a wildcard router, if there is one registered
71
81
  result = if @routes.key?('ANY')
72
- @routes['ANY'].call(request)
73
- else
74
- :not_found
75
- end
82
+ @routes['ANY'].call(request)
83
+ else
84
+ :not_found
85
+ end
76
86
  end
77
87
 
78
88
  if result == :not_found
79
89
  # no need to try :path as we cannot really know if you've attempted to pass a version through it here
80
90
  # plus we wouldn't have tracked it as unmatched
81
- version = request.version(using: [:header,:params])
91
+ version = request.version
82
92
  attempted_versions = request.unmatched_versions
83
93
  body = "NotFound"
84
94
  unless attempted_versions.empty? || (attempted_versions.size == 1 && attempted_versions.first == 'n/a')
85
95
  body += if version == 'n/a'
86
- ". Your request did not specify an API version.".freeze
87
- else
88
- ". Your request speficied API version = \"#{version}\"."
89
- end
96
+ ". Your request did not specify an API version.".freeze
97
+ else
98
+ ". Your request speficied API version = \"#{version}\"."
99
+ end
90
100
  pretty_versions = attempted_versions.collect(&:inspect).join(', ')
91
101
  body += " Available versions = #{pretty_versions}."
92
102
  end
@@ -0,0 +1,51 @@
1
+ # Originally from:
2
+ # https://github.com/rkh/mustermann/blob/500a603fffe0594ab842d72addcc449eedd6d5be/mustermann/lib/mustermann/router/rack.rb
3
+ # Copied here after its removal from Mustermann proper
4
+
5
+ require 'praxis/router/simple'
6
+
7
+ module Mustermann
8
+ module Router
9
+ # Simple pattern based router that allows matching paths to a given Rack application.
10
+ #
11
+ # @example config.ru
12
+ # router = Mustermann::Rack.new do
13
+ # on '/' do |env|
14
+ # [200, {'Content-Type' => 'text/plain'}, ['Hello World!']]
15
+ # end
16
+ #
17
+ # on '/:name' do |env|
18
+ # name = env['mustermann.params']['name']
19
+ # [200, {'Content-Type' => 'text/plain'}, ["Hello #{name}!"]]
20
+ # end
21
+ #
22
+ # on '/something/*', call: SomeApp
23
+ # end
24
+ #
25
+ # # in a config.ru
26
+ # run router
27
+ class Rack < Simple
28
+ def initialize(env_prefix: "mustermann", params_key: "#{env_prefix}.params", pattern_key: "#{env_prefix}.pattern", **options, &block)
29
+ @params_key, @pattern_key = params_key, pattern_key
30
+ options[:default] = [404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["Not Found"]] unless options.include? :default
31
+ super(**options, &block)
32
+ end
33
+
34
+ def invoke(callback, env, params, pattern)
35
+ params_was, pattern_was = env[@params_key], env[@pattern_key]
36
+ env[@params_key], env[@pattern_key] = params, pattern
37
+ response = callback.call(env)
38
+ response[1].each { |k,v| throw :pass if k.downcase == 'x-cascade' and v == 'pass' }
39
+ response
40
+ ensure
41
+ env[@params_key], env[@pattern_key] = params_was, pattern_was
42
+ end
43
+
44
+ def string_for(env)
45
+ env['PATH_INFO']
46
+ end
47
+
48
+ private :invoke, :string_for
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,146 @@
1
+ # Originally from:
2
+ # https://github.com/rkh/mustermann/blob/500a603fffe0594ab842d72addcc449eedd6d5be/mustermann/lib/mustermann/router/simple.rb
3
+ # Copied here after its removal from Mustermann proper
4
+
5
+ require 'mustermann'
6
+
7
+ module Mustermann
8
+ module Router
9
+ # Simple pattern based router that allows matching a string to a given callback.
10
+ #
11
+ # @example
12
+ # require 'mustermann/router/simple'
13
+ #
14
+ # router = Mustermann::Router::Simple.new do
15
+ # on ':name/:sub' do |string, params|
16
+ # params['sub']
17
+ # end
18
+ #
19
+ # on 'foo' do
20
+ # "bar"
21
+ # end
22
+ # end
23
+ #
24
+ # router.call("foo") # => "bar"
25
+ # router.call("a/b") # => "b"
26
+ # router.call("bar") # => nil
27
+ class Simple
28
+ # Default value for when no pattern matches
29
+ attr_accessor :default
30
+
31
+ # @example with a default value
32
+ # require 'mustermann/router/simple'
33
+ #
34
+ # router = Mustermann::Router::Simple.new(default: 42)
35
+ # router.on(':name', capture: :digit) { |string| string.to_i }
36
+ # router.call("23") # => 23
37
+ # router.call("example") # => 42
38
+ #
39
+ # @example block with implicit receiver
40
+ # require 'mustermann/router/simple'
41
+ #
42
+ # router = Mustermann::Router::Simple.new do
43
+ # on('/foo') { 'foo' }
44
+ # on('/bar') { 'bar' }
45
+ # end
46
+ #
47
+ # @example block with explicit receiver
48
+ # require 'mustermann/router/simple'
49
+ #
50
+ # router = Mustermann::Router::Simple.new(type: :rails) do |r|
51
+ # r.on('/foo') { 'foo' }
52
+ # r.on('/bar') { 'bar' }
53
+ # end
54
+ #
55
+ # @param default value to be returned if nothing matches
56
+ # @param options [Hash] pattern options
57
+ # @return [Mustermann::Router::Simple] new router instance
58
+ def initialize(default: nil, **options, &block)
59
+ @options = options
60
+ @map = []
61
+ @default = default
62
+
63
+ block.arity == 0 ? instance_eval(&block) : yield(self) if block
64
+ end
65
+
66
+ # @example
67
+ # require 'mustermann/router/simple'
68
+ #
69
+ # router = Mustermann::Router::Simple.new
70
+ # router.on(':a/:b') { 42 }
71
+ # router['foo/bar'] # => <#Proc:...>
72
+ # router['foo_bar'] # => nil
73
+ #
74
+ # @return [#call, nil] callback for given string, if a pattern matches
75
+ def [](string)
76
+ string = string_for(string) unless string.is_a? String
77
+ @map.detect { |p,v| p === string }[1]
78
+ end
79
+
80
+ # @example
81
+ # require 'mustermann/router/simple'
82
+ #
83
+ # router = Mustermann::Router::Simple.new
84
+ # router['/:name'] = proc { |string, params| params['name'] }
85
+ # router.call('/foo') # => "foo"
86
+ #
87
+ # @param pattern [String, Mustermann::Pattern] matcher
88
+ # @param callback [#call] callback to call on match
89
+ # @see #on
90
+ def []=(pattern, callback)
91
+ on(pattern, call: callback)
92
+ end
93
+
94
+ # @example with block
95
+ # require 'mustermann/router/simple'
96
+ #
97
+ # router = Mustermann::Router::Simple.new
98
+ #
99
+ # router.on(':a/:b') { 42 }
100
+ # router.call('foo/bar') # => 42
101
+ # router.call('foo_bar') # => nil
102
+ #
103
+ # @example with callback option
104
+ # require 'mustermann/router/simple'
105
+ #
106
+ # callback = proc { 42 }
107
+ # router = Mustermann::Router::Simple.new
108
+ #
109
+ # router.on(':a/:b', call: callback)
110
+ # router.call('foo/bar') # => 42
111
+ # router.call('foo_bar') # => nil
112
+ #
113
+ # @param patterns [Array<String, Pattern>]
114
+ # @param call [#call] callback object, need to hand in block if missing
115
+ # @param options [Hash] pattern options
116
+ def on(*patterns, call: Proc.new, **options)
117
+ patterns.each do |pattern|
118
+ pattern = Mustermann.new(pattern.to_str, **options, **@options) if pattern.respond_to? :to_str
119
+ @map << [pattern, call]
120
+ end
121
+ end
122
+
123
+ # Finds the matching callback and calls `call` on it with the given input and the params.
124
+ # @return the callback's return value
125
+ def call(input)
126
+ @map.each do |pattern, callback|
127
+ catch(:pass) do
128
+ next unless params = pattern.params(string_for(input))
129
+ return invoke(callback, input, params, pattern)
130
+ end
131
+ end
132
+ @default
133
+ end
134
+
135
+ def invoke(callback, input, params, pattern)
136
+ callback.call(input, params)
137
+ end
138
+
139
+ def string_for(input)
140
+ input.to_str
141
+ end
142
+
143
+ private :invoke, :string_for
144
+ end
145
+ end
146
+ end