grape-app 0.3.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9786d097c5c829ddf0628b46d4205fbbb82dd3ac
4
+ data.tar.gz: 8d9b2b6524336370ea0944cf836ab55f83a187d9
5
+ SHA512:
6
+ metadata.gz: 4d4ff67a6ed976dd8d1e4e18e7de26f12e6da49873a7c339412adfe3456ed5a3f1ca3ae4f624e53d61a75479fe72c46a6e2d85f7883d4d2adc4b725cdb63d0d0
7
+ data.tar.gz: 58c318856bbe67e1a96dea8e4a873e2a0aef478c9833cf76a7dd4336b804a2502e64ce864a87810616a3058485498e6e29d82dfea7392e00ca83d3d4753e3d0e
@@ -0,0 +1 @@
1
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
@@ -0,0 +1,92 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ grape-app (0.3.0)
5
+ activesupport
6
+ activesupport-json_encoder
7
+ grape
8
+ grape-entity
9
+ hashie-forbidden_attributes
10
+ rack-cors
11
+
12
+ GEM
13
+ remote: https://rubygems.org/
14
+ specs:
15
+ activesupport (4.2.1)
16
+ i18n (~> 0.7)
17
+ json (~> 1.7, >= 1.7.7)
18
+ minitest (~> 5.1)
19
+ thread_safe (~> 0.3, >= 0.3.4)
20
+ tzinfo (~> 1.1)
21
+ activesupport-json_encoder (1.1.0)
22
+ activesupport (>= 4.1.0, < 5.0)
23
+ axiom-types (0.1.1)
24
+ descendants_tracker (~> 0.0.4)
25
+ ice_nine (~> 0.11.0)
26
+ thread_safe (~> 0.3, >= 0.3.1)
27
+ builder (3.2.2)
28
+ coercible (1.0.0)
29
+ descendants_tracker (~> 0.0.1)
30
+ descendants_tracker (0.0.4)
31
+ thread_safe (~> 0.3, >= 0.3.1)
32
+ diff-lcs (1.2.5)
33
+ equalizer (0.0.11)
34
+ grape (0.11.0)
35
+ activesupport
36
+ builder
37
+ hashie (>= 2.1.0)
38
+ multi_json (>= 1.3.2)
39
+ multi_xml (>= 0.5.2)
40
+ rack (>= 1.3.0)
41
+ rack-accept
42
+ rack-mount
43
+ virtus (>= 1.0.0)
44
+ grape-entity (0.4.5)
45
+ activesupport
46
+ multi_json (>= 1.3.2)
47
+ hashie (3.4.2)
48
+ hashie-forbidden_attributes (0.1.1)
49
+ hashie (>= 3.0)
50
+ i18n (0.7.0)
51
+ ice_nine (0.11.1)
52
+ json (1.8.3)
53
+ minitest (5.7.0)
54
+ multi_json (1.11.1)
55
+ multi_xml (0.5.5)
56
+ rack (1.6.1)
57
+ rack-accept (0.4.5)
58
+ rack (>= 0.4)
59
+ rack-cors (0.3.1)
60
+ rack-mount (0.8.3)
61
+ rack (>= 1.0.0)
62
+ rake (10.4.2)
63
+ rspec (3.3.0)
64
+ rspec-core (~> 3.3.0)
65
+ rspec-expectations (~> 3.3.0)
66
+ rspec-mocks (~> 3.3.0)
67
+ rspec-core (3.3.0)
68
+ rspec-support (~> 3.3.0)
69
+ rspec-expectations (3.3.0)
70
+ diff-lcs (>= 1.2.0, < 2.0)
71
+ rspec-support (~> 3.3.0)
72
+ rspec-mocks (3.3.0)
73
+ diff-lcs (>= 1.2.0, < 2.0)
74
+ rspec-support (~> 3.3.0)
75
+ rspec-support (3.3.0)
76
+ thread_safe (0.3.5)
77
+ tzinfo (1.2.2)
78
+ thread_safe (~> 0.1)
79
+ virtus (1.0.5)
80
+ axiom-types (~> 0.1)
81
+ coercible (~> 1.0)
82
+ descendants_tracker (~> 0.0, >= 0.0.3)
83
+ equalizer (~> 0.0, >= 0.0.9)
84
+
85
+ PLATFORMS
86
+ ruby
87
+
88
+ DEPENDENCIES
89
+ bundler
90
+ grape-app!
91
+ rake
92
+ rspec
@@ -0,0 +1,32 @@
1
+ # Grape::App
2
+
3
+ Grape::App is an attempt to 'railsify' the process of developing standalone grape apps.
4
+
5
+ ## TODO
6
+
7
+ * Write app generator
8
+
9
+ ## Licence
10
+
11
+ ```
12
+ Copyright (c) 2015 Black Square Media
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining
15
+ a copy of this software and associated documentation files (the
16
+ "Software"), to deal in the Software without restriction, including
17
+ without limitation the rights to use, copy, modify, merge, publish,
18
+ distribute, sublicense, and/or sell copies of the Software, and to
19
+ permit persons to whom the Software is furnished to do so, subject to
20
+ the following conditions:
21
+
22
+ The above copyright notice and this permission notice shall be
23
+ included in all copies or substantial portions of the Software.
24
+
25
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32
+ ```
@@ -0,0 +1,6 @@
1
+ require 'bundler/setup'
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ task default: :spec
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'grape-app'
5
+ s.version = '0.3.0'
6
+ s.authors = ['Black Square Media Ltd']
7
+ s.email = ['info@blacksquaremedia.com']
8
+ s.summary = %{Stanalone Grape API apps}
9
+ s.description = %{}
10
+ s.homepage = 'https://github.com/bsm/grape-app'
11
+ s.license = 'MIT'
12
+
13
+ s.files = `git ls-files`.lines.map(&:chomp)
14
+ s.test_files = `git ls-files -- test/*`.lines.map(&:chomp)
15
+ s.require_paths = ['lib']
16
+ s.required_ruby_version = '>= 1.9.3'
17
+
18
+ s.add_dependency 'grape'
19
+ s.add_dependency 'grape-entity'
20
+ s.add_dependency 'activesupport'
21
+ s.add_dependency 'activesupport-json_encoder'
22
+ s.add_dependency 'hashie-forbidden_attributes'
23
+ s.add_dependency 'rack-cors'
24
+
25
+ s.add_development_dependency 'bundler'
26
+ s.add_development_dependency 'rake'
27
+ s.add_development_dependency 'rspec'
28
+ end
29
+
@@ -0,0 +1 @@
1
+ require 'grape/app'
@@ -0,0 +1,84 @@
1
+ require 'bundler/setup'
2
+ require 'pathname'
3
+ require 'grape'
4
+ require 'active_support/string_inquirer'
5
+ require 'active_support/configurable'
6
+ require 'active_support/inflector/methods'
7
+ require 'activesupport/json_encoder'
8
+ require 'hashie-forbidden_attributes'
9
+ require 'rack/cors'
10
+
11
+ class Grape::App < Grape::API
12
+ include ActiveSupport::Configurable
13
+
14
+ class << self
15
+
16
+ # Run initializers
17
+ def init!(root = nil)
18
+ @root = Pathname.new(root) if root
19
+
20
+ # Require bundle
21
+ Bundler.require :default, env.to_sym
22
+
23
+ # Load initializers
24
+ require 'grape/app/initializers/pre'
25
+ require_one 'config', 'environments', env
26
+ require_all 'config', 'initializers'
27
+ require 'grape/app/initializers/post'
28
+
29
+ # Load app
30
+ $LOAD_PATH.push @root.join('lib')
31
+ $LOAD_PATH.push @root.join('app')
32
+ $LOAD_PATH.push @root.join('app', 'models')
33
+
34
+ require_one 'app', 'models'
35
+ require_one 'app', 'api'
36
+ end
37
+
38
+ # @return [Pathname] root path
39
+ def root
40
+ @root ||= Bundler.root.dup
41
+ end
42
+
43
+ # @return [ActiveSupport::StringInquirer] env name
44
+ def env
45
+ @env ||= ActiveSupport::StringInquirer.new(ENV['GRAPE_ENV'] || ENV['RACK_ENV'] || 'development')
46
+ end
47
+
48
+ def autoload(paths)
49
+ paths.each do |path|
50
+ Object.autoload ActiveSupport::Inflector.classify(path), path
51
+ end
52
+ end
53
+
54
+ def middleware
55
+ config = self.config
56
+ @middleware ||= Rack::Builder.new do
57
+ use Rack::SslEnforcer if config.force_ssl
58
+ use Rack::Cors do
59
+ allow do
60
+ origins *Array.wrap(config.cors_allow_origins)
61
+ resource '*', headers: :any, methods: [:get, :post, :options, :delete, :put]
62
+ end
63
+ end if config.cors_allow_origins
64
+
65
+ run Grape::App
66
+ end
67
+ end
68
+
69
+ private
70
+
71
+ def require_all(*args)
72
+ args = args + ['**', '*.rb']
73
+ Dir[root.join(*args).to_s].each {|f| require f }
74
+ end
75
+
76
+ def require_one(*args)
77
+ path = root.join(*args).to_s
78
+ require path if File.exists?("#{path}.rb")
79
+ end
80
+
81
+ end
82
+ end
83
+
84
+ require 'grape/app/helpers'
@@ -0,0 +1,6 @@
1
+ module Grape::App::Helpers
2
+ extend ActiveSupport::Autoload
3
+
4
+ autoload :Params
5
+ autoload :RespondWith
6
+ end
@@ -0,0 +1,9 @@
1
+ module Grape::App::Helpers::Params
2
+
3
+ # Scope declared params
4
+ # @return [Hashie::Mash] decalred params only
5
+ def declared_params
6
+ declared(params, include_missing: false)
7
+ end
8
+
9
+ end
@@ -0,0 +1,18 @@
1
+ require 'grape_entity'
2
+
3
+ module Grape::App::Helpers::RespondWith
4
+
5
+ class Errors < Grape::Entity
6
+ expose :errors
7
+ end
8
+
9
+ # @param [ActiveRecord::Base] record validated record
10
+ def respond_with(record, opts = {})
11
+ unless record.errors.empty?
12
+ opts[:with] = Errors
13
+ status 400
14
+ end
15
+ present record, opts
16
+ end
17
+
18
+ end
@@ -0,0 +1,17 @@
1
+ if Grape::App.config.raise_on_missing_translations
2
+ handler = -> (exception, *) { exception = exception.to_exception if exception.respond_to?(:to_exception); raise exception }
3
+ I18n.exception_handler = handler
4
+ end
5
+
6
+ if defined?(ActiveRecord)
7
+ require 'yaml'
8
+
9
+ configurations = YAML.load(Grape::App.root.join('config', 'database.yml').read)
10
+ configurations[Grape::App.env.to_s]['url'] = ENV['DATABASE_URL'] if ENV['DATABASE_URL']
11
+
12
+ ActiveRecord::Base.configurations = configurations
13
+ ActiveRecord::Base.default_timezone = :utc
14
+ ActiveRecord::Base.establish_connection(Grape::App.env.to_sym)
15
+
16
+ Grape::App.middleware.use ActiveRecord::ConnectionAdapters::ConnectionManagement
17
+ end
@@ -0,0 +1,9 @@
1
+ # Set default time-zone
2
+ Time.zone = 'UTC'
3
+
4
+ # Configure big-decimal encoding
5
+ ActiveSupport.encode_big_decimal_as_string = false
6
+
7
+ # Add default I18n paths and set default locale
8
+ I18n.load_path += Dir[Grape::App.root.join('config', 'locales', '*.{rb,yml}').to_s]
9
+ I18n.default_locale = :en
@@ -0,0 +1,3 @@
1
+ if defined?(ActiveRecord)
2
+ load 'grape/app/tasks/databases.rake'
3
+ end
@@ -0,0 +1,47 @@
1
+ load 'active_record/railties/databases.rake'
2
+
3
+ ActiveRecord::Tasks::DatabaseTasks.tap do |config|
4
+ config.db_dir = 'db'
5
+ config.migrations_paths = ['db/migrate']
6
+ config.seed_loader = Class.new do
7
+ def self.load_seed
8
+ load Grape::App.root.join('db', 'seeds.rb').to_s
9
+ end
10
+ end
11
+ end
12
+
13
+ namespace :db do
14
+
15
+ Rake::Task['load_config'].clear
16
+
17
+ task load_config: :environment do
18
+ ActiveRecord::Tasks::DatabaseTasks.tap do |config|
19
+ config.root = Grape::App.root
20
+ config.env = Grape::App.env
21
+ config.database_configuration = ActiveRecord::Base.configurations
22
+ end
23
+ end
24
+
25
+ desc "Create a new migration using NAME"
26
+ task migration: :environment do
27
+ abort "No NAME specified. Example usage: `rake db:migration NAME=create_widgets`" unless ENV["NAME"]
28
+
29
+ name = ENV["NAME"]
30
+ path = File.join(ActiveRecord::Migrator.migrations_path, "#{Time.now.utc.strftime('%Y%m%d%H%M%S')}_#{name}.rb")
31
+
32
+ FileUtils.mkdir_p(ActiveRecord::Migrator.migrations_path)
33
+ File.write path, <<-MIGRATION.strip_heredoc
34
+ class #{name.camelize} < ActiveRecord::Migration
35
+ def change
36
+ end
37
+ end
38
+ MIGRATION
39
+ puts path
40
+ end
41
+
42
+ namespace :test do
43
+ desc "Prepare test DB"
44
+ task :prepare
45
+ end
46
+
47
+ end
@@ -0,0 +1 @@
1
+ require 'grape/app'
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Grape::App do
4
+
5
+ subject { described_class }
6
+ before { subject.init! File.expand_path('../../scenario', __FILE__) }
7
+
8
+ it 'should have an env' do
9
+ expect(subject.env).to be_instance_of(ActiveSupport::StringInquirer)
10
+ expect(subject.env).to eq("development")
11
+ end
12
+
13
+ it 'should have an root' do
14
+ expect(subject.root).to be_instance_of(Pathname)
15
+ end
16
+
17
+ it 'should be an API' do
18
+ expect(subject).to be < Grape::API
19
+ end
20
+
21
+ it 'should init with default time zone' do
22
+ expect(Time.zone.name).to eq("UTC")
23
+ end
24
+
25
+ it 'should configure i18n' do
26
+ expect(I18n.load_path).to include(subject.root.join("config", "locales", "en.yml").to_s)
27
+ expect(I18n.default_locale).to eq(:en)
28
+ expect(I18n.exception_handler).to be_instance_of(Proc)
29
+ end
30
+
31
+ it 'should read env specific initializers' do
32
+ expect(subject.config).to eq(
33
+ dev_specific: true,
34
+ raise_on_missing_translations: true,
35
+ cors_allow_origins: ["example.com"],
36
+ )
37
+ end
38
+
39
+ it 'should prepare middleware' do
40
+ expect(subject.middleware).to be_instance_of(Rack::Builder)
41
+ expect(subject.middleware.send(:instance_variable_get, :@use).size).to eq(1)
42
+ expect(subject.middleware.send(:instance_variable_get, :@run)).to eq(subject)
43
+ end
44
+
45
+ end
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'grape-app', path: '../../'
@@ -0,0 +1,5 @@
1
+ Grape::App.configure do |c|
2
+ c.dev_specific = true
3
+ c.raise_on_missing_translations = true
4
+ c.cors_allow_origins = ['example.com']
5
+ end
@@ -0,0 +1,2 @@
1
+ en:
2
+ hi: hello
@@ -0,0 +1,2 @@
1
+ class MyLib
2
+ end
@@ -0,0 +1 @@
1
+ require 'grape-app'
metadata ADDED
@@ -0,0 +1,192 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: grape-app
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Black Square Media Ltd
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: grape
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: grape-entity
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: activesupport
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
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport-json_encoder
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: hashie-forbidden_attributes
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rack-cors
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: bundler
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: ''
140
+ email:
141
+ - info@blacksquaremedia.com
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - ".gitignore"
147
+ - Gemfile
148
+ - Gemfile.lock
149
+ - README.md
150
+ - Rakefile
151
+ - grape-app.gemspec
152
+ - lib/grape-app.rb
153
+ - lib/grape/app.rb
154
+ - lib/grape/app/helpers.rb
155
+ - lib/grape/app/helpers/params.rb
156
+ - lib/grape/app/helpers/respond_with.rb
157
+ - lib/grape/app/initializers/post.rb
158
+ - lib/grape/app/initializers/pre.rb
159
+ - lib/grape/app/tasks.rake
160
+ - lib/grape/app/tasks/databases.rake
161
+ - lib/grape_app.rb
162
+ - spec/grape/app_spec.rb
163
+ - spec/scenario/Gemfile
164
+ - spec/scenario/config/environments/development.rb
165
+ - spec/scenario/config/locales/en.yml
166
+ - spec/scenario/lib/my_lib.rb
167
+ - spec/spec_helper.rb
168
+ homepage: https://github.com/bsm/grape-app
169
+ licenses:
170
+ - MIT
171
+ metadata: {}
172
+ post_install_message:
173
+ rdoc_options: []
174
+ require_paths:
175
+ - lib
176
+ required_ruby_version: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: 1.9.3
181
+ required_rubygems_version: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - ">="
184
+ - !ruby/object:Gem::Version
185
+ version: '0'
186
+ requirements: []
187
+ rubyforge_project:
188
+ rubygems_version: 2.4.7
189
+ signing_key:
190
+ specification_version: 4
191
+ summary: Stanalone Grape API apps
192
+ test_files: []