praxis 2.0.pre.8 → 2.0.pre.13

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 (242) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.ruby-version +1 -1
  4. data/.travis.yml +1 -3
  5. data/CHANGELOG.md +33 -0
  6. data/TODO.md +1 -4
  7. data/bin/praxis +67 -12
  8. data/lib/praxis.rb +10 -3
  9. data/lib/praxis/action_definition.rb +15 -13
  10. data/lib/praxis/action_definition/headers_dsl_compiler.rb +0 -7
  11. data/lib/praxis/api_general_info.rb +1 -1
  12. data/lib/praxis/application.rb +6 -2
  13. data/lib/praxis/blueprint.rb +357 -0
  14. data/lib/praxis/bootloader.rb +9 -3
  15. data/lib/praxis/bootloader_stages/environment.rb +16 -13
  16. data/lib/praxis/collection.rb +1 -11
  17. data/lib/praxis/config_hash.rb +44 -0
  18. data/lib/praxis/docs/{openapi → open_api}/info_object.rb +18 -10
  19. data/lib/praxis/docs/{openapi → open_api}/media_type_object.rb +0 -0
  20. data/lib/praxis/docs/{openapi → open_api}/operation_object.rb +0 -0
  21. data/lib/praxis/docs/{openapi → open_api}/parameter_object.rb +0 -0
  22. data/lib/praxis/docs/{openapi → open_api}/paths_object.rb +0 -0
  23. data/lib/praxis/docs/{openapi → open_api}/request_body_object.rb +0 -0
  24. data/lib/praxis/docs/{openapi → open_api}/response_object.rb +0 -0
  25. data/lib/praxis/docs/{openapi → open_api}/responses_object.rb +0 -0
  26. data/lib/praxis/docs/{openapi → open_api}/schema_object.rb +0 -0
  27. data/lib/praxis/docs/{openapi → open_api}/server_object.rb +0 -0
  28. data/lib/praxis/docs/{openapi → open_api}/tag_object.rb +0 -0
  29. data/lib/praxis/docs/open_api_generator.rb +91 -6
  30. data/lib/praxis/endpoint_definition.rb +273 -0
  31. data/lib/praxis/extensions/attribute_filtering/active_record_filter_query_builder.rb +182 -58
  32. data/lib/praxis/extensions/attribute_filtering/filter_tree_node.rb +3 -2
  33. data/lib/praxis/extensions/attribute_filtering/filtering_params.rb +47 -56
  34. data/lib/praxis/extensions/attribute_filtering/filters_parser.rb +153 -0
  35. data/lib/praxis/extensions/attribute_filtering/sequel_filter_query_builder.rb +20 -8
  36. data/lib/praxis/extensions/field_expansion.rb +3 -36
  37. data/lib/praxis/extensions/pagination.rb +5 -32
  38. data/lib/praxis/extensions/pagination/ordering_params.rb +1 -1
  39. data/lib/praxis/extensions/pagination/pagination_params.rb +6 -4
  40. data/lib/praxis/field_expander.rb +90 -0
  41. data/lib/praxis/finalizable.rb +34 -0
  42. data/lib/praxis/mapper/active_model_compat.rb +4 -0
  43. data/lib/praxis/mapper/resource.rb +18 -2
  44. data/lib/praxis/mapper/selector_generator.rb +2 -1
  45. data/lib/praxis/mapper/sequel_compat.rb +7 -0
  46. data/lib/praxis/media_type.rb +3 -68
  47. data/lib/praxis/plugin_concern.rb +1 -1
  48. data/lib/praxis/plugins/mapper_plugin.rb +24 -15
  49. data/lib/praxis/plugins/pagination_plugin.rb +34 -4
  50. data/lib/praxis/renderer.rb +88 -0
  51. data/lib/praxis/request.rb +1 -1
  52. data/lib/praxis/resource_definition.rb +2 -311
  53. data/lib/praxis/response_definition.rb +2 -10
  54. data/lib/praxis/response_template.rb +3 -3
  55. data/lib/praxis/router.rb +2 -2
  56. data/lib/praxis/routing_config.rb +1 -1
  57. data/lib/praxis/tasks/api_docs.rb +17 -64
  58. data/lib/praxis/tasks/routes.rb +1 -1
  59. data/lib/praxis/types/media_type_common.rb +1 -11
  60. data/lib/praxis/version.rb +1 -1
  61. data/praxis.gemspec +0 -1
  62. data/spec/functional_spec.rb +5 -9
  63. data/spec/praxis/action_definition_spec.rb +12 -20
  64. data/spec/praxis/blueprint_spec.rb +373 -0
  65. data/spec/praxis/bootloader_spec.rb +10 -2
  66. data/spec/praxis/collection_spec.rb +0 -13
  67. data/spec/praxis/config_hash_spec.rb +64 -0
  68. data/spec/praxis/{resource_definition_spec.rb → endpoint_definition_spec.rb} +37 -64
  69. data/spec/praxis/extensions/attribute_filtering/active_record_filter_query_builder_spec.rb +249 -168
  70. data/spec/praxis/extensions/attribute_filtering/filter_tree_node_spec.rb +25 -6
  71. data/spec/praxis/extensions/attribute_filtering/filtering_params_spec.rb +190 -8
  72. data/spec/praxis/extensions/attribute_filtering/filters_parser_spec.rb +140 -0
  73. data/spec/praxis/extensions/field_expansion_spec.rb +5 -24
  74. data/spec/praxis/extensions/field_selection/active_record_query_selector_spec.rb +1 -1
  75. data/spec/praxis/extensions/field_selection/sequel_query_selector_spec.rb +1 -1
  76. data/spec/praxis/extensions/support/spec_resources_active_model.rb +1 -1
  77. data/spec/praxis/field_expander_spec.rb +149 -0
  78. data/spec/praxis/mapper/selector_generator_spec.rb +1 -1
  79. data/spec/praxis/media_type_identifier_spec.rb +5 -4
  80. data/spec/praxis/media_type_spec.rb +4 -93
  81. data/spec/praxis/renderer_spec.rb +188 -0
  82. data/spec/praxis/response_definition_spec.rb +0 -31
  83. data/spec/praxis/response_spec.rb +1 -1
  84. data/spec/praxis/router_spec.rb +8 -8
  85. data/spec/praxis/routing_config_spec.rb +3 -3
  86. data/spec/spec_app/app/controllers/instances.rb +13 -7
  87. data/spec/spec_app/design/media_types/instance.rb +1 -19
  88. data/spec/spec_app/design/media_types/volume.rb +1 -1
  89. data/spec/spec_app/design/media_types/volume_snapshot.rb +2 -14
  90. data/spec/spec_app/design/resources/instances.rb +5 -8
  91. data/spec/spec_app/design/resources/volume_snapshots.rb +1 -1
  92. data/spec/spec_app/design/resources/volumes.rb +1 -1
  93. data/spec/support/spec_authorization_plugin.rb +1 -1
  94. data/spec/support/spec_blueprints.rb +72 -0
  95. data/spec/support/{spec_resource_definitions.rb → spec_endpoint_definitions.rb} +2 -2
  96. data/spec/support/spec_media_types.rb +6 -26
  97. data/tasks/thor/app.rb +8 -34
  98. data/tasks/thor/example.rb +51 -285
  99. data/tasks/thor/model.rb +40 -0
  100. data/tasks/thor/scaffold.rb +117 -0
  101. data/tasks/thor/templates/generator/empty_app/.gitignore +0 -1
  102. data/tasks/thor/templates/generator/empty_app/Gemfile +7 -23
  103. data/tasks/thor/templates/generator/empty_app/README.md +1 -1
  104. data/tasks/thor/templates/generator/empty_app/Rakefile +4 -13
  105. data/tasks/thor/templates/generator/empty_app/{design/response_templates → app/v1/resources}/.empty_directory +0 -0
  106. data/tasks/thor/templates/generator/empty_app/{design/response_templates → app/v1/resources}/.gitkeep +0 -0
  107. data/tasks/thor/templates/generator/empty_app/config/environment.rb +26 -17
  108. data/tasks/thor/templates/generator/empty_app/{design/v1/resources → config/initializers}/.empty_directory +0 -0
  109. data/tasks/thor/templates/generator/empty_app/{design/v1/resources → config/initializers}/.gitkeep +0 -0
  110. data/tasks/thor/templates/generator/empty_app/design/v1/endpoints/.empty_directory +0 -0
  111. data/tasks/thor/templates/generator/empty_app/design/v1/endpoints/.gitkeep +0 -0
  112. data/tasks/thor/templates/generator/empty_app/docs/.empty_directory +0 -0
  113. data/tasks/thor/templates/generator/empty_app/docs/.gitkeep +0 -0
  114. data/tasks/thor/templates/generator/empty_app/spec/spec_helper.rb +14 -9
  115. data/tasks/thor/templates/generator/example_app/.gitignore +1 -0
  116. data/tasks/thor/templates/generator/example_app/Gemfile +19 -0
  117. data/tasks/thor/templates/generator/example_app/Rakefile +61 -0
  118. data/tasks/thor/templates/generator/example_app/app/models/user.rb +6 -0
  119. data/tasks/thor/templates/generator/example_app/app/v1/concerns/controller_base.rb +24 -0
  120. data/tasks/thor/templates/generator/example_app/app/v1/controllers/users.rb +17 -0
  121. data/tasks/thor/templates/generator/example_app/app/v1/resources/base.rb +11 -0
  122. data/tasks/thor/templates/generator/example_app/app/v1/resources/user.rb +25 -0
  123. data/tasks/thor/templates/generator/example_app/config.ru +30 -0
  124. data/tasks/thor/templates/generator/example_app/config/environment.rb +41 -0
  125. data/tasks/thor/templates/generator/example_app/db/migrate/20201010101010_create_users_table.rb +12 -0
  126. data/tasks/thor/templates/generator/example_app/db/seeds.rb +6 -0
  127. data/tasks/thor/templates/generator/example_app/design/api.rb +18 -0
  128. data/tasks/thor/templates/generator/example_app/design/v1/endpoints/users.rb +37 -0
  129. data/tasks/thor/templates/generator/example_app/design/v1/media_types/user.rb +21 -0
  130. data/tasks/thor/templates/generator/example_app/spec/helpers/database_helper.rb +20 -0
  131. data/tasks/thor/templates/generator/example_app/spec/spec_helper.rb +42 -0
  132. data/tasks/thor/templates/generator/example_app/spec/v1/controllers/users_spec.rb +37 -0
  133. data/tasks/thor/templates/generator/scaffold/design/endpoints/collection.rb +98 -0
  134. data/tasks/thor/templates/generator/scaffold/design/media_types/item.rb +18 -0
  135. data/tasks/thor/templates/generator/scaffold/implementation/controllers/collection.rb +77 -0
  136. data/tasks/thor/templates/generator/scaffold/implementation/resources/base.rb +11 -0
  137. data/tasks/thor/templates/generator/scaffold/implementation/resources/item.rb +45 -0
  138. data/tasks/thor/templates/generator/scaffold/models/active_record.rb +6 -0
  139. data/tasks/thor/templates/generator/scaffold/models/sequel.rb +6 -0
  140. metadata +64 -136
  141. data/lib/api_browser/.bowerrc +0 -3
  142. data/lib/api_browser/.editorconfig +0 -21
  143. data/lib/api_browser/Gruntfile.js +0 -581
  144. data/lib/api_browser/app/index.html +0 -59
  145. data/lib/api_browser/app/js/app.js +0 -48
  146. data/lib/api_browser/app/js/controllers/action.js +0 -47
  147. data/lib/api_browser/app/js/controllers/controller.js +0 -10
  148. data/lib/api_browser/app/js/controllers/menu.js +0 -93
  149. data/lib/api_browser/app/js/controllers/trait.js +0 -10
  150. data/lib/api_browser/app/js/controllers/type.js +0 -24
  151. data/lib/api_browser/app/js/directives/attribute_description.js +0 -56
  152. data/lib/api_browser/app/js/directives/attribute_table.js +0 -28
  153. data/lib/api_browser/app/js/directives/conditional_requirements.js +0 -13
  154. data/lib/api_browser/app/js/directives/fixed_if_fits.js +0 -38
  155. data/lib/api_browser/app/js/directives/highlight.js +0 -14
  156. data/lib/api_browser/app/js/directives/menu_item.js +0 -59
  157. data/lib/api_browser/app/js/directives/no_container.js +0 -8
  158. data/lib/api_browser/app/js/directives/readable_list.js +0 -87
  159. data/lib/api_browser/app/js/directives/request_examples.js +0 -31
  160. data/lib/api_browser/app/js/directives/type_placeholder.js +0 -30
  161. data/lib/api_browser/app/js/directives/url.js +0 -15
  162. data/lib/api_browser/app/js/factories/Configuration.js +0 -12
  163. data/lib/api_browser/app/js/factories/Documentation.js +0 -61
  164. data/lib/api_browser/app/js/factories/Example.js +0 -51
  165. data/lib/api_browser/app/js/factories/PageInfo.js +0 -9
  166. data/lib/api_browser/app/js/factories/normalize_attributes.js +0 -20
  167. data/lib/api_browser/app/js/factories/prepare_template.js +0 -15
  168. data/lib/api_browser/app/js/factories/template_for.js +0 -128
  169. data/lib/api_browser/app/js/filters/attribute_name.js +0 -10
  170. data/lib/api_browser/app/js/filters/friendly_json.js +0 -5
  171. data/lib/api_browser/app/js/filters/has_requirement.js +0 -14
  172. data/lib/api_browser/app/js/filters/header_info.js +0 -9
  173. data/lib/api_browser/app/js/filters/is_empty.js +0 -8
  174. data/lib/api_browser/app/js/filters/markdown.js +0 -6
  175. data/lib/api_browser/app/js/filters/resource_name.js +0 -5
  176. data/lib/api_browser/app/js/filters/tag_requirement.js +0 -13
  177. data/lib/api_browser/app/sass/modules/_body.scss +0 -40
  178. data/lib/api_browser/app/sass/modules/_cloke.scss +0 -8
  179. data/lib/api_browser/app/sass/modules/_header.scss +0 -10
  180. data/lib/api_browser/app/sass/modules/_nav.scss +0 -7
  181. data/lib/api_browser/app/sass/modules/_sidebar.scss +0 -134
  182. data/lib/api_browser/app/sass/modules/_switch.scss +0 -55
  183. data/lib/api_browser/app/sass/modules/_table.scss +0 -13
  184. data/lib/api_browser/app/sass/praxis.scss +0 -70
  185. data/lib/api_browser/app/sass/variables/_bootstrap-variables.scss +0 -774
  186. data/lib/api_browser/app/views/action.html +0 -97
  187. data/lib/api_browser/app/views/builtin/field-selector.html +0 -24
  188. data/lib/api_browser/app/views/controller.html +0 -55
  189. data/lib/api_browser/app/views/directives/attribute_description.html +0 -2
  190. data/lib/api_browser/app/views/directives/attribute_description/default.html +0 -2
  191. data/lib/api_browser/app/views/directives/attribute_description/example.html +0 -13
  192. data/lib/api_browser/app/views/directives/attribute_description/headers.html +0 -8
  193. data/lib/api_browser/app/views/directives/attribute_description/member_options.html +0 -4
  194. data/lib/api_browser/app/views/directives/attribute_description/values.html +0 -14
  195. data/lib/api_browser/app/views/directives/attribute_table.html +0 -17
  196. data/lib/api_browser/app/views/directives/menu_item.html +0 -8
  197. data/lib/api_browser/app/views/directives/url.html +0 -3
  198. data/lib/api_browser/app/views/examples/general.html +0 -26
  199. data/lib/api_browser/app/views/home.html +0 -5
  200. data/lib/api_browser/app/views/layout.html +0 -8
  201. data/lib/api_browser/app/views/menu.html +0 -42
  202. data/lib/api_browser/app/views/navbar.html +0 -9
  203. data/lib/api_browser/app/views/trait.html +0 -13
  204. data/lib/api_browser/app/views/type.html +0 -6
  205. data/lib/api_browser/app/views/type/details.html +0 -33
  206. data/lib/api_browser/app/views/types/embedded/array.html +0 -2
  207. data/lib/api_browser/app/views/types/embedded/default.html +0 -12
  208. data/lib/api_browser/app/views/types/embedded/field-selector.html +0 -13
  209. data/lib/api_browser/app/views/types/embedded/links.html +0 -11
  210. data/lib/api_browser/app/views/types/embedded/requirements.html +0 -6
  211. data/lib/api_browser/app/views/types/embedded/single_req.html +0 -9
  212. data/lib/api_browser/app/views/types/embedded/struct.html +0 -14
  213. data/lib/api_browser/app/views/types/label/link.html +0 -1
  214. data/lib/api_browser/app/views/types/label/primitive.html +0 -1
  215. data/lib/api_browser/app/views/types/label/primitive_collection.html +0 -1
  216. data/lib/api_browser/app/views/types/label/type.html +0 -1
  217. data/lib/api_browser/app/views/types/label/type_collection.html +0 -1
  218. data/lib/api_browser/app/views/types/main/array.html +0 -22
  219. data/lib/api_browser/app/views/types/main/default.html +0 -23
  220. data/lib/api_browser/app/views/types/main/hash.html +0 -23
  221. data/lib/api_browser/app/views/types/standalone/array.html +0 -3
  222. data/lib/api_browser/app/views/types/standalone/default.html +0 -18
  223. data/lib/api_browser/app/views/types/standalone/struct.html +0 -2
  224. data/lib/api_browser/bower_template.json +0 -41
  225. data/lib/api_browser/package-lock.json +0 -7110
  226. data/lib/api_browser/package.json +0 -43
  227. data/lib/praxis/docs/generator.rb +0 -243
  228. data/lib/praxis/docs/link_builder.rb +0 -30
  229. data/lib/praxis/links.rb +0 -135
  230. data/lib/praxis/types/multipart.rb +0 -109
  231. data/spec/api_browser/directives/type_placeholder_spec.js +0 -134
  232. data/spec/api_browser/factories/configuration_spec.js +0 -32
  233. data/spec/api_browser/factories/documentation_spec.js +0 -100
  234. data/spec/api_browser/factories/normalize_attributes_spec.js +0 -92
  235. data/spec/api_browser/factories/template_for_spec.js +0 -67
  236. data/spec/api_browser/filters/attribute_name_spec.js +0 -23
  237. data/spec/praxis/types/multipart_spec.rb +0 -112
  238. data/tasks/thor/templates/generator/empty_app/.rspec +0 -1
  239. data/tasks/thor/templates/generator/empty_app/Guardfile +0 -3
  240. data/tasks/thor/templates/generator/empty_app/config/rainbows.rb +0 -57
  241. data/tasks/thor/templates/generator/empty_app/docs/app.js +0 -1
  242. data/tasks/thor/templates/generator/empty_app/docs/styles.scss +0 -3
@@ -82,7 +82,7 @@ module Praxis
82
82
  PATH_VERSION_PREFIX
83
83
  end
84
84
 
85
- # DEPRECATED: remove with ResourceDefinition.version using: :path
85
+ # DEPRECATED: remove with EndpointDefinition.version using: :path
86
86
  PATH_VERSION_MATCHER = %r{^#{self.path_version_prefix}(?<version>[^\/]+)\/}.freeze
87
87
 
88
88
  def path_version_matcher
@@ -1,312 +1,3 @@
1
- require 'active_support/concern'
2
- require 'active_support/inflector'
3
1
 
4
- module Praxis
5
- module ResourceDefinition
6
- extend ActiveSupport::Concern
7
-
8
- DEFAULT_RESOURCE_HREF_ACTION = :show
9
-
10
- included do
11
- @version = 'n/a'.freeze
12
- @actions = Hash.new
13
- @responses = Hash.new
14
-
15
- @action_defaults = Trait.new &ResourceDefinition.generate_defaults_block
16
-
17
- @version_options = {}
18
- @metadata = {}
19
- @traits = []
20
-
21
- if self.name
22
- @prefix = '/' + self.name.split("::").last.underscore
23
- else
24
- @prefix = '/'
25
- end
26
-
27
- @version_prefix = ''
28
-
29
- @parent = nil
30
- @parent_prefix = ''
31
-
32
- @routing_prefix = nil
33
-
34
- @on_finalize = Array.new
35
-
36
- Application.instance.resource_definitions << self
37
- end
38
-
39
- def self.generate_defaults_block( version: nil )
40
-
41
- # Ensure we inherit any base params defined in the API definition for the passed in version
42
- base_attributes = if (base_params = ApiDefinition.instance.info(version).base_params)
43
- base_params.attributes
44
- else
45
- {}
46
- end
47
-
48
- Proc.new do
49
- unless base_attributes.empty?
50
- params do
51
- base_attributes.each do |base_name, base_attribute|
52
- attribute base_name, base_attribute.type, **base_attribute.options
53
- end
54
- end
55
- end
56
- end
57
- end
58
-
59
- def self.finalize!
60
- Application.instance.resource_definitions.each do |resource_definition|
61
- while (block = resource_definition.on_finalize.shift)
62
- block.call
63
- end
64
- end
65
- end
66
-
67
-
68
-
69
- module ClassMethods
70
- attr_reader :actions
71
- attr_reader :responses
72
- attr_reader :version_options
73
- attr_reader :traits
74
- attr_reader :version_prefix
75
- attr_reader :parent_prefix
76
-
77
- # opaque hash of user-defined medata, used to decorate the definition,
78
- # and also available in the generated JSON documents
79
- attr_reader :metadata
80
-
81
- attr_accessor :controller
82
-
83
- def display_name( string=nil )
84
- unless string
85
- return @display_name ||= self.name.split("::").last # Best guess at a display name?
86
- end
87
- @display_name = string
88
- end
89
-
90
- def on_finalize(&block)
91
- if block_given?
92
- @on_finalize << proc(&block)
93
- end
94
-
95
- @on_finalize
96
- end
97
-
98
- def prefix(prefix=nil)
99
- return @prefix if prefix.nil?
100
- @routing_prefix = nil # reset routing_prefix
101
- @prefix = prefix
102
- end
103
-
104
- def media_type(media_type=nil)
105
- return @media_type if media_type.nil?
106
-
107
- if media_type.kind_of?(String)
108
- media_type = SimpleMediaType.new(media_type)
109
- end
110
- @media_type = media_type
111
- end
112
-
113
-
114
- def parent(parent=nil, **mapping)
115
- return @parent if parent.nil?
116
-
117
- @routing_prefix = nil # reset routing_prefix
118
-
119
- parent_action = parent.canonical_path
120
- parent_route = parent_action.route.path
121
-
122
- # if a mapping is passed, it *must* resolve any param name conflicts
123
- unless mapping.any?
124
- # assume last capture is the relevant one to replace
125
- # if not... then I quit.
126
- parent_param_name = parent_route.names.last
127
-
128
- # more assumptions about names
129
- parent_name = parent.name.demodulize.underscore.singularize
130
-
131
- # put it together to find what we should call this new param
132
- param = "#{parent_name}_#{parent_param_name}".to_sym
133
- mapping[parent_param_name.to_sym] = param
134
- end
135
-
136
- # complete the mapping and massage the route
137
- parent_route.names.collect(&:to_sym).each do |name|
138
- if mapping.key?(name)
139
- param = mapping[name]
140
- # FIXME: this won't handle URI Template type paths, ie '/{parent_id}'
141
- prefixed_path = parent_action.route.prefixed_path
142
- @parent_prefix = prefixed_path.gsub(/(:)(#{name})(\W+|$)/, "\\1#{param.to_s}\\3")
143
- else
144
- mapping[name] = name
145
- end
146
- end
147
-
148
- self.on_finalize do
149
- self.inherit_params_from_parent(parent_action, **mapping)
150
- end
151
-
152
- @parent = parent
153
- end
154
-
155
- def inherit_params_from_parent(parent_action, **mapping)
156
- actions.each do |name, action|
157
- action.params do
158
- mapping.each do |parent_name, name|
159
- next if action.params && action.params.attributes.key?(name)
160
-
161
- parent_attribute = parent_action.params.attributes[parent_name]
162
-
163
- attribute name, parent_attribute.type, **parent_attribute.options
164
- end
165
- end
166
- end
167
-
168
- end
169
-
170
- attr_writer :routing_prefix
171
-
172
- def routing_prefix
173
- return @routing_prefix if @routing_prefix
174
-
175
- @routing_prefix = parent_prefix + prefix
176
- end
177
-
178
-
179
- def version(version=nil, options=nil)
180
- return @version unless version
181
-
182
- @version = version
183
-
184
- unless options.nil?
185
- warn 'DEPRECATED: ResourceDefinition.version with options is no longer supported. Define in api global info instead.'
186
-
187
- @version_options = options
188
- version_using = Array(@version_options[:using])
189
- if version_using.include?(:path)
190
- @version_prefix = "#{Praxis::Request::path_version_prefix}#{self.version}"
191
- end
192
- end
193
-
194
- @action_defaults.instance_eval &ResourceDefinition.generate_defaults_block( version: version )
195
- end
196
-
197
-
198
- def canonical_path(action_name=nil)
199
- if action_name
200
- raise "Canonical path for #{self.name} is already defined as: '#{@canonical_action_name}'. 'canonical_path' can only be defined once." if @canonical_action_name
201
- @canonical_action_name = action_name
202
- else
203
- # Resolution of the actual action definition needs to be done lazily, since we can use the `canonical_path` stanza
204
- # at the top of the resource, well before the actual action is defined.
205
- unless @canonical_action
206
- href_action = @canonical_action_name || DEFAULT_RESOURCE_HREF_ACTION
207
- @canonical_action = actions.fetch(href_action) do
208
- raise "Error: trying to set canonical_href of #{self.name}. Action '#{href_action}' does not exist"
209
- end
210
- end
211
- return @canonical_action
212
- end
213
- end
214
-
215
- def to_href( params )
216
- canonical_path.route.path.expand(params)
217
- end
218
-
219
- def parse_href(path)
220
- if path.kind_of?(::URI::Generic)
221
- path = path.path
222
- end
223
- param_values = canonical_path.route.path.params(path)
224
- attrs = canonical_path.params.attributes
225
- param_values.each_with_object({}) do |(key,value),hash|
226
- hash[key.to_sym] = attrs[key.to_sym].load(value,[key])
227
- end
228
- rescue => e
229
- raise Praxis::Exception.new("Error parsing or coercing parameters from href: #{path}\n"+e.message)
230
- end
231
-
232
- def trait(trait_name)
233
- unless ApiDefinition.instance.traits.has_key? trait_name
234
- raise Exceptions::InvalidTrait.new("Trait #{trait_name} not found in the system")
235
- end
236
- trait = ApiDefinition.instance.traits.fetch(trait_name)
237
- @traits << trait_name
238
- end
239
- alias_method :use, :trait
240
-
241
- def action_defaults(&block)
242
- if block_given?
243
- @action_defaults.instance_eval(&block)
244
- end
245
-
246
- @action_defaults
247
- end
248
-
249
- def params(type=Attributor::Struct, **opts, &block)
250
- warn 'DEPRECATED: ResourceDefinition.params is deprecated. Use it in action_defaults instead.'
251
- action_defaults do
252
- params type, **opts, &block
253
- end
254
- end
255
-
256
- def payload(type=Attributor::Struct, **opts, &block)
257
- warn 'DEPRECATED: ResourceDefinition.payload is deprecated. Use action_defaults instead.'
258
- action_defaults do
259
- payload type, **opts, &block
260
- end
261
- end
262
-
263
- def headers(**opts, &block)
264
- warn 'DEPRECATED: ResourceDefinition.headers is deprecated. Use action_defaults instead.'
265
- action_defaults do
266
- headers **opts, &block
267
- end
268
- end
269
-
270
- def response(name, **args)
271
- warn 'DEPRECATED: ResourceDefinition.response is deprecated. Use action_defaults instead.'
272
- action_defaults do
273
- response name, **args
274
- end
275
- end
276
-
277
- def action(name, &block)
278
- raise ArgumentError, "can not create ActionDefinition without block" unless block_given?
279
- raise ArgumentError, "Action names must be defined using symbols (Got: #{name} (of type #{name.class}))" unless name.is_a? Symbol
280
- @actions[name] = ActionDefinition.new(name, self, &block)
281
- end
282
-
283
- def description(text=nil)
284
- @description = text if text
285
- @description
286
- end
287
-
288
- def id
289
- self.name.gsub('::'.freeze,'-'.freeze)
290
- end
291
-
292
- def describe(context: nil)
293
- {}.tap do |hash|
294
- hash[:description] = description
295
- hash[:media_type] = media_type.describe(true) if media_type
296
- hash[:actions] = actions.values.collect{|action| action.describe(context: context)}
297
- hash[:name] = self.name
298
- hash[:parent] = self.parent.id if self.parent
299
- hash[:display_name] = self.display_name
300
- hash[:metadata] = metadata
301
- hash[:traits] = self.traits
302
- end
303
- end
304
-
305
- def nodoc!
306
- metadata[:doc_visibility] = :none
307
- end
308
-
309
- end
310
-
311
- end
312
- end
2
+ raise "ResourceDefinition class has changed name in this version of Praxis.\n" \
3
+ 'Please blanket-replace all uses of ResourceDefinition with EndpointDefinition instead.'
@@ -311,16 +311,8 @@ module Praxis
311
311
  def validate_parts!(response)
312
312
  return unless parts
313
313
 
314
- case response.body
315
- when Praxis::Types::MultipartArray
316
- response.body.each do |part|
317
- parts.validate(part)
318
- end
319
- else
320
- # TODO: remove with other Multipart deprecations.
321
- response.parts.each do |name, part|
322
- parts.validate(part)
323
- end
314
+ response.body.each do |part|
315
+ parts.validate(part)
324
316
  end
325
317
  end
326
318
 
@@ -9,15 +9,15 @@ module Praxis
9
9
  end
10
10
 
11
11
  def compile(action=nil, **args)
12
- # Default media_type to the resource_definition one, if the block has it in
12
+ # Default media_type to the endpoint_definition one, if the block has it in
13
13
  # its required args but no value is passed (funky, but can help in the common case)
14
14
  if block.parameters.any? { |(type, name)| name == :media_type && type == :keyreq } && action
15
15
  unless args.has_key? :media_type
16
- media_type = action.resource_definition.media_type
16
+ media_type = action.endpoint_definition.media_type
17
17
  unless media_type
18
18
  raise Exceptions::InvalidConfiguration.new(
19
19
  "Could not default :media_type argument for response template #{@name}." +
20
- " Resource #{action.resource_definition} does not have an associated mediatype and none was passed"
20
+ " Endpoint #{action.endpoint_definition} does not have an associated mediatype and none was passed"
21
21
  )
22
22
  end
23
23
  args[:media_type] = media_type
data/lib/praxis/router.rb CHANGED
@@ -52,8 +52,8 @@ module Praxis
52
52
  def add_route(target, route)
53
53
  path_versioning = (Application.instance.versioning_scheme == :path)
54
54
 
55
- # DEPRECATED: remove with ResourceDefinition.version using: :path
56
- path_versioning ||= (target.action.resource_definition.version_options[:using] == :path)
55
+ # DEPRECATED: remove with EndpointDefinition.version using: :path
56
+ path_versioning ||= (target.action.endpoint_definition.version_options[:using] == :path)
57
57
 
58
58
  unless path_versioning
59
59
  target = VersionMatcher.new(target, version: route.version)
@@ -53,7 +53,7 @@ module Praxis
53
53
  end
54
54
  prefixed_path = path.gsub('//','/')
55
55
  path = (base + path).gsub('//','/')
56
- pattern = Mustermann.new(path, {ignore_unknown_options: true}.merge( options ))
56
+ pattern = Mustermann.new(path, **{ignore_unknown_options: true}.merge( options ))
57
57
  @route = Route.new(verb, pattern, version, prefixed_path: prefixed_path, **options)
58
58
  end
59
59
 
@@ -2,68 +2,8 @@ namespace :praxis do
2
2
 
3
3
  namespace :docs do
4
4
 
5
- def base_path
6
- require 'uri'
7
- documentation_url = Praxis::ApiDefinition.instance.global_info.documentation_url
8
- URI(documentation_url).path.gsub(/\/[^\/]*$/, '/') if documentation_url
9
- end
10
-
11
- path = File.expand_path(File.join(File.dirname(__FILE__), '../../api_browser'))
12
-
13
- desc "Install dependencies"
14
- task :install do
15
- unless system("npm install --production", chdir: path)
16
- raise Exception.new("NPM Install Failed")
17
- end
18
-
19
- docs_dir = File.join(Dir.pwd, 'docs')
20
- FileUtils.mkdir_p docs_dir unless File.directory? docs_dir
21
-
22
- # The doc browser will need to have a minimal app.js and styles.css file at the root
23
- # Let's add them if the app has not overriden them
24
- js_file = File.join(Dir.pwd, 'docs', 'app.js')
25
- scss_file = File.join(Dir.pwd, 'docs', 'styles.scss')
26
- template_directory = File.expand_path(File.join(File.dirname(__FILE__), '../../../tasks/thor/templates/generator/empty_app/docs'))
27
-
28
- unless File.exists? js_file
29
- FileUtils.cp File.join(template_directory, 'app.js'), js_file
30
- end
31
- unless File.exists? scss_file
32
- FileUtils.cp File.join(template_directory, 'styles.scss'), scss_file
33
- end
34
- end
35
-
36
- desc "Run API Documentation Browser"
37
- task :preview, [:port] => [:install, :generate] do |t, args|
38
- doc_port = args[:port] || '9090'
39
- exec({
40
- 'USER_DOCS_PATH' => File.join(Dir.pwd, 'docs'),
41
- 'DOC_PORT' => doc_port,
42
- 'PLUGIN_PATHS' => Praxis::Application.instance.doc_browser_plugin_paths.join(':'),
43
- 'BASE_PATH' => '/'
44
- }, "#{path}/node_modules/.bin/grunt serve --gruntfile '#{path}/Gruntfile.js'")
45
- end
46
-
47
- desc "Build docs that can be shipped"
48
- task :build => [:install, :generate] do
49
- exec({
50
- 'USER_DOCS_PATH' => File.join(Dir.pwd, 'docs'),
51
- 'PLUGIN_PATHS' => Praxis::Application.instance.doc_browser_plugin_paths.join(':'),
52
- 'BASE_PATH' => base_path
53
- }, "#{path}/node_modules/.bin/grunt build --gruntfile '#{path}/Gruntfile.js'")
54
- end
55
-
56
- desc "Generate API docs (JSON definitions) for a Praxis App"
57
- task :generate => [:environment] do |t, args|
58
- require 'fileutils'
59
-
60
- Praxis::Blueprint.caching_enabled = false
61
- generator = Praxis::Docs::Generator.new(Dir.pwd)
62
- generator.save!
63
- end
64
-
65
5
  desc "Generate OpenAPI 3 docs for a Praxis App"
66
- task :openapi => [:environment] do |t, args|
6
+ task :generate => [:environment] do |t, args|
67
7
  require 'fileutils'
68
8
 
69
9
  Praxis::Blueprint.caching_enabled = false
@@ -72,7 +12,7 @@ namespace :praxis do
72
12
  end
73
13
 
74
14
  desc "Preview (and Generate) OpenAPI 3 docs for a Praxis App"
75
- task :openapipreview => [:openapi] do |t, args|
15
+ task :preview => [:generate] do |t, args|
76
16
  require 'webrick'
77
17
  docs_port = 9090
78
18
  root = Dir.pwd + '/docs/openapi/'
@@ -81,9 +21,22 @@ namespace :praxis do
81
21
  trap('INT') { s.shutdown }
82
22
  s.start
83
23
  end
84
- `open http://localhost:#{docs_port}/`
24
+ # If there is only 1 version we'll feature it and open the browser onto it
25
+ versions = Dir.children(root)
26
+ featured_version = (versions.size < 2) ? "#{versions.first}/" : ''
27
+ `open http://localhost:#{docs_port}/#{featured_version}`
85
28
  wb.join
86
29
  end
87
-
30
+ desc "Generate and package all OpenApi Docs into a zip, ready for a Web server (like S3...) to present it"
31
+ task :package => [:generate] do |t, args|
32
+ docs_root = Dir.pwd + '/docs/openapi/'
33
+ zip_file = Dir.pwd + '/docs/openapi.zip'
34
+ `rm -f #{zip_file}`
35
+ # NOTE: This assumes the "zip" utility is installed, supporting the recursive flag.
36
+ `zip -r #{zip_file} #{docs_root}`
37
+ puts
38
+ puts "Left packaged API docs in #{zip_file}"
39
+ puts " --> To view the docs, unzip the file under a web server (or S3...) and access the index.hml files from a browser"
40
+ end
88
41
  end
89
42
  end