unival 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +23 -0
- data/LICENSE.txt +20 -0
- data/README.md +58 -0
- data/Rakefile +36 -0
- data/lib/unival.rb +4 -0
- data/lib/unival/app.rb +102 -0
- data/lib/unival/version.rb +3 -0
- data/spec/full_stack_spec.rb +111 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/unival_spec.rb +7 -0
- data/unival.gemspec +80 -0
- metadata +199 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a822304c582ef5a96eea091e3875402301be4076
|
4
|
+
data.tar.gz: bec7f1eb5bd5cabd1f1fd8afa286a534f8d2829a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b6353ba23aa5206a4442c59607892a112b965159c93ebd8e43a5329f688c4505103fdc909d42c402aa1aa358e37772a28badd5e8ebcda31e81bc91e58a842ad3
|
7
|
+
data.tar.gz: 84c7f7f04d1a4dbf590620a8083ec22cc3e5c5a0d7a3bfab5bd4d29a37eae649a4d8bf40848e6ba250112632fe5ad1f1fa0a0f2e1aec69945aee47df9a272f14
|
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
# We test both with AR 4 and AR3, see gemfiles/ for more.
|
4
|
+
# To run specs against specific versions of dependencies, use
|
5
|
+
#
|
6
|
+
# $ BUNDLE_GEMFILE=gemfiles/Gemfile.rails-4.1.x bundle exec rake
|
7
|
+
#
|
8
|
+
# etc.
|
9
|
+
gem 'activemodel', "> 3"
|
10
|
+
gem 'rack', '~> 1.4'
|
11
|
+
|
12
|
+
# Add dependencies to develop your gem here.
|
13
|
+
# Include everything needed to run rake, tests, features, etc.
|
14
|
+
group :development do
|
15
|
+
gem 'activerecord'
|
16
|
+
gem 'rack-test'
|
17
|
+
gem 'rake', '~> 10.0'
|
18
|
+
gem 'yard'
|
19
|
+
gem 'sqlite3'
|
20
|
+
gem "rspec", "~> 3.4"
|
21
|
+
gem "bundler", "~> 1.0"
|
22
|
+
gem "jeweler", '~> 2.1'
|
23
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2016 WeTransfer
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# unival
|
2
|
+
|
3
|
+
A no-frills RESTful validation service for ActiveModel. Helps for the cases where you found that doing client-side
|
4
|
+
validations is a bad idea. It is just an endpoint.
|
5
|
+
|
6
|
+
# How to use it
|
7
|
+
|
8
|
+
Mount it into your application (Rails or otherwise). Then, send it a request like so:
|
9
|
+
|
10
|
+
POST /?model=User
|
11
|
+
|
12
|
+
with a JSON body of:
|
13
|
+
|
14
|
+
{"name": "John Doe"}
|
15
|
+
|
16
|
+
`POST` implies you want to check if you are able to create an object.
|
17
|
+
The app is going to instantiate a blank User model object, perform `user#attributes = your_attributes` and is going to call
|
18
|
+
`valid?` on it. If it isn't valid, you are going to receive the errors back:
|
19
|
+
|
20
|
+
{
|
21
|
+
"model": "User",
|
22
|
+
"is_create": true,
|
23
|
+
"valid": false,
|
24
|
+
"errors": {
|
25
|
+
"name": [
|
26
|
+
"has already been taken"
|
27
|
+
]
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
If it is valid, you the `valid` property in the JSON response will be `true`, and the `errors` property will be set to `null`.
|
32
|
+
To perform a check for a modification, use `PUT` or `PATCH` (`ActiveModel#attributes=` works rather like a `Hash#merge`, not like a
|
33
|
+
full-on replace assignment).
|
34
|
+
|
35
|
+
PUT /?model=User&id=123
|
36
|
+
|
37
|
+
will give the same response as the POST example, except that `is_create` will be set to `true`.
|
38
|
+
|
39
|
+
## Concerns
|
40
|
+
|
41
|
+
This approach is relatively insecure as it allows for probing. Use something like `Rack::Attack` to limit the number of
|
42
|
+
checks from a single IP/browser combination. Even then, use this sparingly. You may also restrict the models that can be validated
|
43
|
+
from this endpoint by overriding `model_accessible?(model_module)`
|
44
|
+
|
45
|
+
## Contributing to unival
|
46
|
+
|
47
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
48
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
49
|
+
* Fork the project.
|
50
|
+
* Start a feature/bugfix branch.
|
51
|
+
* Commit and push until you are happy with your contribution.
|
52
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
53
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
54
|
+
|
55
|
+
## Copyright
|
56
|
+
|
57
|
+
Copyright (c) 2016 WeTransfer. See LICENSE.txt for further details.
|
58
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
require_relative 'lib/unival/version'
|
16
|
+
Jeweler::Tasks.new do |gem|
|
17
|
+
gem.version = Unival::VERSION
|
18
|
+
# gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
|
19
|
+
gem.name = "unival"
|
20
|
+
gem.homepage = "http://github.com/WeTransfer/unival"
|
21
|
+
gem.license = "MIT"
|
22
|
+
gem.summary = %Q{ Generic ActiveModel validation via REST }
|
23
|
+
gem.description = %Q{ A minimal endpoint for driving server-side validations from a remote UI }
|
24
|
+
gem.email = "me@julik.nl"
|
25
|
+
gem.authors = ["Julik Tarkhanov"]
|
26
|
+
# dependencies defined in Gemfile
|
27
|
+
end
|
28
|
+
|
29
|
+
Jeweler::RubygemsDotOrgTasks.new
|
30
|
+
|
31
|
+
require 'rspec/core/rake_task'
|
32
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
33
|
+
t.rspec_opts = ["-c", "-f progress", "-r ./spec/spec_helper.rb"]
|
34
|
+
t.pattern = 'spec/**/*_spec.rb'
|
35
|
+
end
|
36
|
+
task :default => :spec
|
data/lib/unival.rb
ADDED
data/lib/unival/app.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
class Unival::App
|
4
|
+
SUPPORTED_METHODS = %w( PUT POST PATCH )
|
5
|
+
Inv = Class.new(StandardError)
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
req = Rack::Request.new(env)
|
9
|
+
|
10
|
+
# Only support POST, PUT and PATCH
|
11
|
+
if !SUPPORTED_METHODS.include?(env['REQUEST_METHOD'])
|
12
|
+
e = {error: 'Unsupported HTTP method %s' % env['REQUEST_METHOD']}
|
13
|
+
return [406, {'Content-Type' => 'application/json', 'Allow' => 'POST,PUT,PATCH'}, [JSON.dump(e)]]
|
14
|
+
end
|
15
|
+
|
16
|
+
params = JSON.load(env['rack.input'].read)
|
17
|
+
|
18
|
+
query_params = extract_query_or_route_params_from(req)
|
19
|
+
|
20
|
+
model_class_name = query_params.delete('model')
|
21
|
+
raise Inv, "No model class given (by default passed as the `model' query-string param)" unless model_class_name.present?
|
22
|
+
|
23
|
+
model_class = Kernel.const_get(model_class_name)
|
24
|
+
raise Inv, "Invalid model or model not permitted" unless model_accessible?(model_class)
|
25
|
+
|
26
|
+
model = if req.post?
|
27
|
+
raise Inv, "The model module does not support .new" unless model_class.respond_to?(:new)
|
28
|
+
model_class.new
|
29
|
+
else
|
30
|
+
model_id = query_params.delete('id')
|
31
|
+
raise Inv, "No model ID to find given (by default passed as the `id' query-string param)" unless model_id
|
32
|
+
raise Inv, "The model module does not support .find" unless model_class.respond_to?(:find)
|
33
|
+
model_class.find(model_id)
|
34
|
+
end
|
35
|
+
|
36
|
+
model_data = if query_params['format'].to_s.downcase == 'jquery'
|
37
|
+
repack_jquery_serialization(model_class_name, params)
|
38
|
+
else
|
39
|
+
params
|
40
|
+
end
|
41
|
+
|
42
|
+
# Instead of scanning for instance_methods, check the object itself.
|
43
|
+
raise Inv, "The model does not support `#valid?'" unless model.respond_to?(:valid?)
|
44
|
+
|
45
|
+
# Despite what you might think, attributes= ONLY updates the attributes given in the argument.
|
46
|
+
model.attributes = model_data
|
47
|
+
|
48
|
+
is_create = req.post?
|
49
|
+
if model.valid?
|
50
|
+
d = {model: model_class, is_create: is_create, valid: true, errors: nil}
|
51
|
+
[200, {'Content-Type' => 'application/json'}, [JSON.dump(d)]]
|
52
|
+
else
|
53
|
+
d = {model: model_class, is_create: is_create, valid: false, errors: model.errors.as_json}
|
54
|
+
[409, {'Content-Type' => 'application/json'}, [JSON.dump(d)]]
|
55
|
+
end
|
56
|
+
rescue Exception => e
|
57
|
+
if e.to_s =~ /NotFound/
|
58
|
+
d = {error: "Model not found: #{e}"}
|
59
|
+
[404, {'Content-Type' => 'application/json'}, [JSON.dump(d)]]
|
60
|
+
elsif e === Inv
|
61
|
+
d = {error: e.message}
|
62
|
+
[400, {'Content-Type' => 'application/json'}, [JSON.dump(d)]]
|
63
|
+
[]
|
64
|
+
else
|
65
|
+
d = {error: e.message}
|
66
|
+
[502, {'Content-Type' => 'application/json'}, [JSON.dump(d)]]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Tells whether it is permitted to validate a given Module object as an ActiveModel.
|
71
|
+
# You might want to restrict this further. The default permits everything.
|
72
|
+
def model_accessible?(model_module)
|
73
|
+
true
|
74
|
+
end
|
75
|
+
|
76
|
+
# Logs the exception for later use
|
77
|
+
def log_exception(e)
|
78
|
+
$stderr.puts e.message
|
79
|
+
end
|
80
|
+
|
81
|
+
# Extract params like :format, :id and :model
|
82
|
+
def extract_query_or_route_params_from(rack_request)
|
83
|
+
Rack::Utils.parse_nested_query(rack_request.query_string)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Hackishly use Rack to reconstruct a hash of keys-values, with nesting
|
87
|
+
def repack_jquery_serialization(model_class_name, jquery_array_of_fields)
|
88
|
+
reassembled_query = jquery_array_of_fields.map do |elem|
|
89
|
+
Rack::Utils.escape(elem.fetch('name')) + '=' + Rack::Utils.escape(elem.fetch('value'))
|
90
|
+
end.join('&')
|
91
|
+
|
92
|
+
param_hash = Rack::Utils.parse_nested_query(reassembled_query)
|
93
|
+
|
94
|
+
raise "The resulting parametric object must be a Hash" unless param_hash.is_a?(Hash)
|
95
|
+
raise "The resulting parametric object must have 1 key" unless param_hash.keys.one?
|
96
|
+
object_params = param_hash.fetch(param_hash.keys[0])
|
97
|
+
|
98
|
+
raise "The resulting unwrapped object params must be a Hash" unless object_params.is_a?(Hash)
|
99
|
+
|
100
|
+
return object_params.with_indifferent_access
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rack'
|
3
|
+
require 'rack/test'
|
4
|
+
require 'active_record'
|
5
|
+
require 'sqlite3'
|
6
|
+
|
7
|
+
describe 'Unival full-stack' do
|
8
|
+
include Rack::Test::Methods
|
9
|
+
let(:app) { Unival::App.new }
|
10
|
+
|
11
|
+
# This is a full-stack speck, so we are going to do real ActiveRecord and stuff.
|
12
|
+
before :all do
|
13
|
+
|
14
|
+
if ActiveRecord::VERSION::MAJOR < 4
|
15
|
+
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', dbfile: ':memory:')
|
16
|
+
else
|
17
|
+
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
|
18
|
+
end
|
19
|
+
|
20
|
+
ActiveRecord::Schema.define do
|
21
|
+
create_table :people do |t|
|
22
|
+
t.string :name, null: false
|
23
|
+
t.string :email, null: true
|
24
|
+
t.integer :items, default: 0
|
25
|
+
end
|
26
|
+
|
27
|
+
create_table :credit_cards do |t|
|
28
|
+
t.string :number, null: false, maxlength: 12
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Person < ActiveRecord::Base
|
33
|
+
validates_presence_of :name
|
34
|
+
validates_uniqueness_of :name
|
35
|
+
validates_format_of :email, with: /\w+@\w+/
|
36
|
+
end
|
37
|
+
|
38
|
+
class CreditCard < ActiveRecord::Base
|
39
|
+
validates_presence_of :number
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
after :each do
|
44
|
+
Person.delete_all
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'performs validation in raw JSON format for a new record and says it may proceed' do
|
48
|
+
post '/?model=Person', JSON.dump({name: 'Julik', email: 'julik@example.com'})
|
49
|
+
parsed = JSON.parse(last_response.body, symbolize_names: true)
|
50
|
+
|
51
|
+
expect(last_response).to be_ok
|
52
|
+
expect(parsed).to eq({:model => "Person", :is_create => true, :valid => true, :errors => nil})
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'performs validation in raw JSON format for a new record and returns an error if the saving would cause a duplicate' do
|
56
|
+
john = Person.create name: 'John', email: 'john@example.com'
|
57
|
+
|
58
|
+
post '/?model=Person', JSON.dump({name: 'John', email: 'another-john@example.com'})
|
59
|
+
parsed = JSON.parse(last_response.body, symbolize_names: true)
|
60
|
+
|
61
|
+
expect(last_response).not_to be_ok
|
62
|
+
expect(last_response.status).to eq(409)
|
63
|
+
expect(parsed).to eq({
|
64
|
+
:model => "Person",
|
65
|
+
:is_create => true,
|
66
|
+
:valid => false,
|
67
|
+
:errors => {:name=>["has already been taken"]}
|
68
|
+
})
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'performs validation in raw JSON format for a record update via PUT and says it may proceed' do
|
72
|
+
john = Person.create name: 'John', email: 'john@example.com'
|
73
|
+
|
74
|
+
put '/?model=Person&id=%d' % john.id, JSON.dump({name: 'John Doe'})
|
75
|
+
|
76
|
+
parsed = JSON.parse(last_response.body, symbolize_names: true)
|
77
|
+
expect(last_response).to be_ok
|
78
|
+
expect(parsed).to eq({:model => "Person", :is_create => false, :valid => true, :errors => nil})
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'performs validation in raw JSON format for a record update via PATCH and says it may proceed' do
|
82
|
+
john = Person.create name: 'John', email: 'john@example.com'
|
83
|
+
|
84
|
+
patch '/?model=Person&id=%d' % john.id, JSON.dump({name: 'John Doe'})
|
85
|
+
|
86
|
+
parsed = JSON.parse(last_response.body, symbolize_names: true)
|
87
|
+
expect(last_response).to be_ok
|
88
|
+
expect(parsed).to eq({:model => "Person", :is_create => false, :valid => true, :errors => nil})
|
89
|
+
end
|
90
|
+
|
91
|
+
describe 'when the model is not permitted for validation' do
|
92
|
+
class MoreRestrictive < Unival::App
|
93
|
+
def model_accessible?(model_class)
|
94
|
+
model_class == Person
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
let(:app) { MoreRestrictive.new }
|
99
|
+
|
100
|
+
it 'performs validation in raw JSON format for a new record and returns an error if the saving would cause a duplicate' do
|
101
|
+
post '/?model=Person', JSON.dump({name: 'John', email: 'john@example.com'})
|
102
|
+
expect(last_response).to be_ok
|
103
|
+
|
104
|
+
post '/?model=CreditCard', JSON.dump({number: '123-123-123-123'})
|
105
|
+
parsed = JSON.parse(last_response.body, symbolize_names: true)
|
106
|
+
|
107
|
+
expect(last_response).not_to be_ok
|
108
|
+
expect(parsed).to eq({error: "Invalid model or model not permitted"})
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/spec/unival_spec.rb
ADDED
data/unival.gemspec
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: unival 0.0.1 ruby lib
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "unival"
|
9
|
+
s.version = "0.0.1"
|
10
|
+
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
13
|
+
s.authors = ["Julik Tarkhanov"]
|
14
|
+
s.date = "2016-05-17"
|
15
|
+
s.description = " A minimal endpoint for driving server-side validations from a remote UI "
|
16
|
+
s.email = "me@julik.nl"
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE.txt",
|
19
|
+
"README.md"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".document",
|
23
|
+
".rspec",
|
24
|
+
"Gemfile",
|
25
|
+
"LICENSE.txt",
|
26
|
+
"README.md",
|
27
|
+
"Rakefile",
|
28
|
+
"lib/unival.rb",
|
29
|
+
"lib/unival/app.rb",
|
30
|
+
"lib/unival/version.rb",
|
31
|
+
"spec/full_stack_spec.rb",
|
32
|
+
"spec/spec_helper.rb",
|
33
|
+
"spec/unival_spec.rb",
|
34
|
+
"unival.gemspec"
|
35
|
+
]
|
36
|
+
s.homepage = "http://github.com/WeTransfer/unival"
|
37
|
+
s.licenses = ["MIT"]
|
38
|
+
s.rubygems_version = "2.2.2"
|
39
|
+
s.summary = "Generic ActiveModel validation via REST"
|
40
|
+
|
41
|
+
if s.respond_to? :specification_version then
|
42
|
+
s.specification_version = 4
|
43
|
+
|
44
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
45
|
+
s.add_runtime_dependency(%q<activemodel>, ["> 3"])
|
46
|
+
s.add_runtime_dependency(%q<rack>, ["~> 1.4"])
|
47
|
+
s.add_development_dependency(%q<activerecord>, [">= 0"])
|
48
|
+
s.add_development_dependency(%q<rack-test>, [">= 0"])
|
49
|
+
s.add_development_dependency(%q<rake>, ["~> 10.0"])
|
50
|
+
s.add_development_dependency(%q<yard>, [">= 0"])
|
51
|
+
s.add_development_dependency(%q<sqlite3>, [">= 0"])
|
52
|
+
s.add_development_dependency(%q<rspec>, ["~> 3.4"])
|
53
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0"])
|
54
|
+
s.add_development_dependency(%q<jeweler>, ["~> 2.1"])
|
55
|
+
else
|
56
|
+
s.add_dependency(%q<activemodel>, ["> 3"])
|
57
|
+
s.add_dependency(%q<rack>, ["~> 1.4"])
|
58
|
+
s.add_dependency(%q<activerecord>, [">= 0"])
|
59
|
+
s.add_dependency(%q<rack-test>, [">= 0"])
|
60
|
+
s.add_dependency(%q<rake>, ["~> 10.0"])
|
61
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
62
|
+
s.add_dependency(%q<sqlite3>, [">= 0"])
|
63
|
+
s.add_dependency(%q<rspec>, ["~> 3.4"])
|
64
|
+
s.add_dependency(%q<bundler>, ["~> 1.0"])
|
65
|
+
s.add_dependency(%q<jeweler>, ["~> 2.1"])
|
66
|
+
end
|
67
|
+
else
|
68
|
+
s.add_dependency(%q<activemodel>, ["> 3"])
|
69
|
+
s.add_dependency(%q<rack>, ["~> 1.4"])
|
70
|
+
s.add_dependency(%q<activerecord>, [">= 0"])
|
71
|
+
s.add_dependency(%q<rack-test>, [">= 0"])
|
72
|
+
s.add_dependency(%q<rake>, ["~> 10.0"])
|
73
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
74
|
+
s.add_dependency(%q<sqlite3>, [">= 0"])
|
75
|
+
s.add_dependency(%q<rspec>, ["~> 3.4"])
|
76
|
+
s.add_dependency(%q<bundler>, ["~> 1.0"])
|
77
|
+
s.add_dependency(%q<jeweler>, ["~> 2.1"])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
metadata
ADDED
@@ -0,0 +1,199 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: unival
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Julik Tarkhanov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-05-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activemodel
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rack
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.4'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activerecord
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
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: rack-test
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
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: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: yard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
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: sqlite3
|
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: rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '3.4'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '3.4'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: bundler
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '1.0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '1.0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: jeweler
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '2.1'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '2.1'
|
153
|
+
description: " A minimal endpoint for driving server-side validations from a remote
|
154
|
+
UI "
|
155
|
+
email: me@julik.nl
|
156
|
+
executables: []
|
157
|
+
extensions: []
|
158
|
+
extra_rdoc_files:
|
159
|
+
- LICENSE.txt
|
160
|
+
- README.md
|
161
|
+
files:
|
162
|
+
- ".document"
|
163
|
+
- ".rspec"
|
164
|
+
- Gemfile
|
165
|
+
- LICENSE.txt
|
166
|
+
- README.md
|
167
|
+
- Rakefile
|
168
|
+
- lib/unival.rb
|
169
|
+
- lib/unival/app.rb
|
170
|
+
- lib/unival/version.rb
|
171
|
+
- spec/full_stack_spec.rb
|
172
|
+
- spec/spec_helper.rb
|
173
|
+
- spec/unival_spec.rb
|
174
|
+
- unival.gemspec
|
175
|
+
homepage: http://github.com/WeTransfer/unival
|
176
|
+
licenses:
|
177
|
+
- MIT
|
178
|
+
metadata: {}
|
179
|
+
post_install_message:
|
180
|
+
rdoc_options: []
|
181
|
+
require_paths:
|
182
|
+
- lib
|
183
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
189
|
+
requirements:
|
190
|
+
- - ">="
|
191
|
+
- !ruby/object:Gem::Version
|
192
|
+
version: '0'
|
193
|
+
requirements: []
|
194
|
+
rubyforge_project:
|
195
|
+
rubygems_version: 2.2.2
|
196
|
+
signing_key:
|
197
|
+
specification_version: 4
|
198
|
+
summary: Generic ActiveModel validation via REST
|
199
|
+
test_files: []
|