mongoid-openapi 0.1.10

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 129684a841b9fb21f50cf4aa28266990c8126d84
4
+ data.tar.gz: 65fc9692a3899fffcdc399e133209a8fb7354471
5
+ SHA512:
6
+ metadata.gz: aa1f46c0515f44063d2825b44bd355f84f4fd9087fb9592b296fb4a0438816888e68f8a8cb8bd20cab599ae3a9c2774e452bc202dc696494f5599f1a03ed052a
7
+ data.tar.gz: 8974002b66c31436ce42deb3bb1f72751b075e00bdb9dfd34416bfb4b0621e19e5c34b142d9a133d3e29dadd5c35485d9b7c65fab2bf29768dab1151bb310293
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .DS_Store
2
+ pkg/**
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright © 2016 [Slate Studio](https://www.slatestudio.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the “Software”), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # Mongoid OpenAPI
2
+
3
+ Rails concern to implement CRUD API controllers for
4
+ [Mongoid](https://github.com/mongodb/mongoid) models using Open API
5
+ ([Swagger](http://swagger.io/)) specification.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,54 @@
1
+ # Holds all default actions for MongoidOpenApi.
2
+ module MongoidOpenApi
3
+ module Actions
4
+ extend ActiveSupport::Concern
5
+ included do
6
+ def index
7
+ @chain = default_scope
8
+
9
+ apply_scopes_to_chain!
10
+ search_filter_chain!
11
+ paginate_chain!
12
+ set_total_count_header!
13
+
14
+ respond_to do |format|
15
+ format.json { render json: @chain.as_json(json_config(:index)) }
16
+ format.csv { render csv: @chain }
17
+ end
18
+ end
19
+
20
+ def show
21
+ object = find_object
22
+ object = get_object_version(object)
23
+ render json: object.as_json(json_config(:show))
24
+ end
25
+
26
+ def create
27
+ object = build_object
28
+ if object.save
29
+ render json: object.as_json(json_config(:create))
30
+ else
31
+ render json: object.errors, status: :unprocessable_entity
32
+ end
33
+ end
34
+
35
+ def update
36
+ object = find_object
37
+ if object.update_attributes(resource_params)
38
+ render json: object.as_json(json_config(:update))
39
+ else
40
+ render json: object.errors, status: :unprocessable_entity
41
+ end
42
+ end
43
+
44
+ def destroy
45
+ object = find_object
46
+ if object.destroy
47
+ render nothing: true, status: 204
48
+ else
49
+ render json: object.errors, status: :unprocessable_entity
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,119 @@
1
+ # Base helpers for MongoidOpenApi work. Some methods here can be overwritten and
2
+ # you will need to do that to customize your controllers.
3
+ module MongoidOpenApi
4
+ module BaseHelpers
5
+ extend ActiveSupport::Concern
6
+ included do
7
+ def default_scope
8
+ resource_class
9
+ end
10
+
11
+ def find_object
12
+ resource_class.find(params[:id])
13
+ end
14
+
15
+ def build_object
16
+ resource_class.new(resource_params)
17
+ end
18
+
19
+ def get_object_version(object)
20
+ version = params[:version]
21
+ if object.respond_to?(:undo, true)
22
+ if version && version.to_i != object.version
23
+ object.undo(nil, from: version.to_i + 1, to: object.version)
24
+ object.version = version
25
+ end
26
+ end
27
+ object
28
+ end
29
+
30
+ def apply_scopes_to_chain!
31
+ if respond_to?(:apply_scopes, true)
32
+ @chain = apply_scopes(@chain)
33
+ end
34
+ end
35
+
36
+ def search_filter_chain!
37
+ query = params[:search]
38
+ if query
39
+ normalized_query = query.to_s.downcase
40
+ @chain = @chain.search(normalized_query, match: :all)
41
+ end
42
+ end
43
+
44
+ def page
45
+ @page ||= params[:page] || false
46
+ end
47
+
48
+ def per_page
49
+ @per_page ||= params[:perPage] || self.class.per_page || 20
50
+ end
51
+
52
+ def paginate_chain!
53
+ @chain = begin
54
+ if page
55
+ @chain.page(page).per(per_page)
56
+ else
57
+ @chain.all
58
+ end
59
+ end
60
+ end
61
+
62
+ def set_total_count_header!
63
+ if page
64
+ response.headers['X-Total-Count'] = @chain.total_count
65
+ else
66
+ response.headers['X-Total-Count'] = @chain.size
67
+ end
68
+ end
69
+
70
+ def resource_class
71
+ @resource_class ||= self.class.resource_class
72
+ @resource_class ||= begin
73
+ namespaced_class = self.class.to_s.split("::").last.
74
+ sub(/Controller$/, "").singularize
75
+ namespaced_class.constantize
76
+ end
77
+ end
78
+
79
+ def resource_request_name
80
+ resource_class.to_s.underscore.gsub("/", "_").gsub("::", "_")
81
+ end
82
+
83
+ def resource_params
84
+ permitted_params
85
+ end
86
+
87
+ def permitted_params
88
+ params.require(resource_request_name).permit!
89
+ end
90
+
91
+ def json_default_options
92
+ @json_default_options ||= begin
93
+ default_options = {}
94
+ json_options = self.class.json_options || {}
95
+ [:only, :except, :methods].each do |name|
96
+ if json_options.key? name
97
+ default_options[name] = json_options[name]
98
+ end
99
+ end
100
+ default_options[:methods] ||= []
101
+ default_options[:methods].concat(JSON_DEFAULT_ATTRIBUTES).uniq!
102
+ default_options
103
+ end
104
+ end
105
+
106
+ def json_config(action)
107
+ json_options = self.class.json_options
108
+ if json_options && json_options.key?(action)
109
+ json_options = json_options[action]
110
+ json_options[:methods] ||= []
111
+ json_options[:methods].concat(JSON_DEFAULT_ATTRIBUTES).uniq!
112
+ json_options
113
+ else
114
+ json_default_options
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,3 @@
1
+ module MongoidOpenApi
2
+ VERSION = '0.1.10'.freeze
3
+ end
@@ -0,0 +1,79 @@
1
+ # =============================================================================
2
+ # MongoidOpenApi
3
+ # Rails concern to implement API controllers for Mongoid models.
4
+ # -----------------------------------------------------------------------------
5
+ # Usage Example:
6
+ #
7
+ # include MongoidApiBase
8
+ #
9
+ # defaults resource_class: Journal::JournalPost,
10
+ # per_page: 30
11
+ #
12
+ # has_scope :by_category
13
+ # has_scope :hidden, type: :boolean
14
+ # has_scope :not_hidden, type: :boolean
15
+ #
16
+ # json_config methods: %w(hex slug sorted_categories opengraph_image_url meta_title meta_description),
17
+ # index: {
18
+ # except: %w(body_markdown body_html),
19
+ # methods: %w(hex slug)
20
+ # }
21
+ # -----------------------------------------------------------------------------
22
+ # Some more ideas for future improvements can be pulled from here:
23
+ # - https://github.com/jamesgolick/resource_controller
24
+ # =============================================================================
25
+
26
+ require 'kaminari'
27
+ require 'csv'
28
+ require 'action_controller/metal/renderers'
29
+ require 'renderers/csv'
30
+ require 'swagger/blocks'
31
+ require 'swagger/generator'
32
+ require 'mongoid-openapi/actions'
33
+ require 'mongoid-openapi/base_helpers'
34
+ require 'mongoid-openapi/version'
35
+
36
+ module MongoidOpenApi
37
+ extend ActiveSupport::Concern
38
+ included do
39
+ respond_to :json
40
+ respond_to :csv, only: %w(index)
41
+
42
+ class_attribute :resource_class
43
+ class_attribute :per_page
44
+ class_attribute :csv_options
45
+ class_attribute :json_options
46
+
47
+ JSON_DEFAULT_ATTRIBUTES = [ :created_at,
48
+ :updated_at,
49
+ :slug,
50
+ :_position,
51
+ :_list_item_title,
52
+ :_list_item_subtitle,
53
+ :_list_item_thumbnail,
54
+ :_document_versions ].freeze
55
+
56
+ include Actions
57
+ include BaseHelpers
58
+ end
59
+
60
+ class_methods do
61
+ def defaults(options)
62
+ if options.key?(:resource_class)
63
+ self.resource_class = options[:resource_class]
64
+ end
65
+
66
+ if options.key?(:per_page)
67
+ self.per_page = options[:per_page]
68
+ end
69
+ end
70
+
71
+ def csv_config(options={})
72
+ self.csv_options = options
73
+ end
74
+
75
+ def json_config(options)
76
+ self.json_options = options
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,33 @@
1
+ ActionController::Renderers.add :csv do |objects, options|
2
+ return "" unless objects.first
3
+
4
+ object_klass = objects.first.class
5
+
6
+ return "" unless object_klass.respond_to? :fields
7
+
8
+ columns = object_klass.fields.keys
9
+ csv_options = self.class.csv_options || {}
10
+
11
+ if csv_options
12
+ if csv_options.key?(:only)
13
+ columns &= csv_options[:only].map(&:to_s)
14
+ end
15
+
16
+ if csv_options.key?(:except)
17
+ columns -= csv_options[:except].map(&:to_s)
18
+ end
19
+
20
+ if csv_options.key?(:methods)
21
+ columns += csv_options[:methods].map(&:to_s)
22
+ end
23
+ end
24
+
25
+ str = CSV.generate do |row|
26
+ row << columns
27
+ objects.each do |obj|
28
+ row << columns.map { |c| obj.send(c) }
29
+ end
30
+ end
31
+
32
+ return str
33
+ end
@@ -0,0 +1,182 @@
1
+ # EXTRA LINKS:
2
+ # - https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md
3
+ # - https://github.com/fotinakis/swagger-blocks
4
+ # - https://github.com/westfieldlabs/apivore
5
+ # - https://github.com/notonthehighstreet/svelte
6
+
7
+ module SwaggerGenerator
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ include Swagger::Blocks
12
+ end
13
+
14
+ class_methods do
15
+ REJECT_NAMES = %w(_id _keywords created_at updated_at).freeze
16
+ ALLOW_TYPES = %w(Object String)
17
+
18
+ def generate_swagger
19
+ generate_swagger_schemas
20
+ generate_swagger_paths
21
+ end
22
+
23
+ def collection_name
24
+ @collection_name ||= to_s.split("::").last.sub(/Controller$/, '')
25
+ end
26
+
27
+ def resource_name
28
+ @resource_name ||= collection_name.singularize
29
+ end
30
+
31
+ def generate_swagger_schemas
32
+ name = resource_name
33
+
34
+ if resource_class
35
+ # TODO: add support for resource class option
36
+ else
37
+ resource_class = name.constantize
38
+ end
39
+
40
+ swagger_schema name do
41
+ # TODO: autogenerate list of required fields
42
+ # key :required, %w(name email)
43
+
44
+ resource_class.fields.each do |name, options|
45
+ type = options.type.to_s
46
+ if ALLOW_TYPES.include? type
47
+ unless REJECT_NAMES.include? name
48
+ property name do
49
+ key :type, :string
50
+ # TODO: autodetect property type
51
+ # key :format, 'date-time'
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ def generate_swagger_paths
60
+ name = resource_name
61
+ plural = collection_name
62
+ path = plural.underscore
63
+ tags = [ plural ]
64
+
65
+ swagger_path "/#{ path }" do
66
+ operation :get do
67
+ key :tags, tags
68
+ key :operationId, "index#{ plural }"
69
+ key :produces, %w(application/json text/csv)
70
+
71
+ parameter do
72
+ key :name, :page
73
+ key :in, :query
74
+ key :required, false
75
+ key :type, :integer
76
+ key :format, :int32
77
+ end
78
+
79
+ parameter do
80
+ key :name, :perPage
81
+ key :in, :query
82
+ key :required, false
83
+ key :type, :integer
84
+ key :format, :int32
85
+ end
86
+
87
+ parameter do
88
+ key :name, :search
89
+ key :in, :query
90
+ key :required, false
91
+ key :type, :string
92
+ end
93
+
94
+ response 200 do
95
+ schema type: :array do
96
+ items do
97
+ key :'$ref', name
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ operation :post do
104
+ key :tags, tags
105
+ key :operationId, "create#{ plural }"
106
+ key :produces, %w(application/json)
107
+ parameter do
108
+ key :name, name.underscore.to_sym
109
+ key :in, :form
110
+ key :required, true
111
+ schema do
112
+ key :'$ref', name # input
113
+ end
114
+ end
115
+ response 200 do
116
+ schema do
117
+ key :'$ref', name
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ swagger_path "/#{ path }/{id}" do
124
+ operation :get do
125
+ key :tags, tags
126
+ key :operationId, "show#{ name }ById"
127
+ key :produces, %w(application/json)
128
+ parameter do
129
+ key :name, :id
130
+ key :in, :path
131
+ key :required, true
132
+ key :type, :string
133
+ end
134
+ response 200 do
135
+ schema do
136
+ key :'$ref', name
137
+ end
138
+ end
139
+ end
140
+
141
+ operation :put do
142
+ key :tags, tags
143
+ key :operationId, "update#{ name }"
144
+ key :produces, %w(application/json)
145
+ parameter do
146
+ key :name, :id
147
+ key :in, :path
148
+ key :required, true
149
+ key :type, :string
150
+ end
151
+ parameter do
152
+ key :name, name.underscore.to_sym
153
+ key :in, :form
154
+ key :required, true
155
+ schema do
156
+ key :'$ref', name # input
157
+ end
158
+ end
159
+ response 200 do
160
+ schema do
161
+ key :'$ref', name
162
+ end
163
+ end
164
+ end
165
+
166
+ operation :delete do
167
+ key :tags, tags
168
+ key :operationId, "delete#{ name }"
169
+ parameter do
170
+ key :name, :id
171
+ key :in, :path
172
+ key :required, true
173
+ key :type, :string
174
+ end
175
+ response 204 do
176
+ key :description, "#{ name } deleted"
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "mongoid-openapi/version"
4
+ require "date"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "mongoid-openapi"
8
+ s.summary = "Rails concern to implement API controllers for Mongoid models using Open API specification."
9
+ s.homepage = "http://github.com/slate-studio/mongoid-openapi"
10
+ s.authors = [ "Alexander Kravets" ]
11
+ s.email = "alex@slatestudio.com"
12
+ s.date = Date.today.strftime("%Y-%m-%d")
13
+ s.extra_rdoc_files = %w[ README.md ]
14
+ s.license = "MIT"
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.require_paths = [ "lib" ]
18
+ s.version = MongoidOpenApi::VERSION
19
+ s.platform = Gem::Platform::RUBY
20
+
21
+ # Ruby ODM framework for MongoDB
22
+ s.add_dependency 'mongoid', '~> 5.0'
23
+ # Clean, powerful, customizable and sophisticated paginator
24
+ s.add_dependency 'kaminari'
25
+ # DSL for pure Ruby code blocks that can be turned into JSON
26
+ s.add_dependency 'swagger-blocks'
27
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongoid-openapi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.10
5
+ platform: ruby
6
+ authors:
7
+ - Alexander Kravets
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-05-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mongoid
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: kaminari
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: swagger-blocks
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description:
56
+ email: alex@slatestudio.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files:
60
+ - README.md
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - LICENSE.md
65
+ - README.md
66
+ - Rakefile
67
+ - lib/mongoid-openapi.rb
68
+ - lib/mongoid-openapi/actions.rb
69
+ - lib/mongoid-openapi/base_helpers.rb
70
+ - lib/mongoid-openapi/version.rb
71
+ - lib/renderers/csv.rb
72
+ - lib/swagger/generator.rb
73
+ - mongoid-openapi.gemspec
74
+ homepage: http://github.com/slate-studio/mongoid-openapi
75
+ licenses:
76
+ - MIT
77
+ metadata: {}
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 2.5.1
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: Rails concern to implement API controllers for Mongoid models using Open
98
+ API specification.
99
+ test_files: []