mongoid-openapi 0.1.10

Sign up to get free protection for your applications and to get access to all the features.
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: []