fmrest 0.10.0 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +2 -0
- data/CHANGELOG.md +38 -0
- data/README.md +194 -763
- metadata +70 -97
- data/.gitignore +0 -26
- data/.rspec +0 -3
- data/.travis.yml +0 -5
- data/Gemfile +0 -3
- data/Rakefile +0 -6
- data/fmrest.gemspec +0 -38
- data/lib/fmrest.rb +0 -29
- data/lib/fmrest/errors.rb +0 -28
- data/lib/fmrest/spyke.rb +0 -21
- data/lib/fmrest/spyke/base.rb +0 -23
- data/lib/fmrest/spyke/container_field.rb +0 -59
- data/lib/fmrest/spyke/model.rb +0 -36
- data/lib/fmrest/spyke/model/associations.rb +0 -82
- data/lib/fmrest/spyke/model/attributes.rb +0 -171
- data/lib/fmrest/spyke/model/auth.rb +0 -35
- data/lib/fmrest/spyke/model/connection.rb +0 -74
- data/lib/fmrest/spyke/model/container_fields.rb +0 -25
- data/lib/fmrest/spyke/model/global_fields.rb +0 -40
- data/lib/fmrest/spyke/model/http.rb +0 -37
- data/lib/fmrest/spyke/model/orm.rb +0 -212
- data/lib/fmrest/spyke/model/serialization.rb +0 -91
- data/lib/fmrest/spyke/model/uri.rb +0 -30
- data/lib/fmrest/spyke/portal.rb +0 -55
- data/lib/fmrest/spyke/relation.rb +0 -359
- data/lib/fmrest/spyke/spyke_formatter.rb +0 -273
- data/lib/fmrest/spyke/validation_error.rb +0 -25
- data/lib/fmrest/string_date.rb +0 -220
- data/lib/fmrest/token_store.rb +0 -6
- data/lib/fmrest/token_store/active_record.rb +0 -74
- data/lib/fmrest/token_store/base.rb +0 -25
- data/lib/fmrest/token_store/memory.rb +0 -26
- data/lib/fmrest/token_store/moneta.rb +0 -41
- data/lib/fmrest/token_store/redis.rb +0 -45
- data/lib/fmrest/v1.rb +0 -21
- data/lib/fmrest/v1/connection.rb +0 -89
- data/lib/fmrest/v1/container_fields.rb +0 -114
- data/lib/fmrest/v1/dates.rb +0 -81
- data/lib/fmrest/v1/paths.rb +0 -47
- data/lib/fmrest/v1/raise_errors.rb +0 -57
- data/lib/fmrest/v1/token_session.rb +0 -142
- data/lib/fmrest/v1/token_store/active_record.rb +0 -13
- data/lib/fmrest/v1/token_store/memory.rb +0 -13
- data/lib/fmrest/v1/type_coercer.rb +0 -192
- data/lib/fmrest/v1/utils.rb +0 -95
- data/lib/fmrest/version.rb +0 -5
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module FmRest
|
4
|
-
module Spyke
|
5
|
-
# ActiveModel 4 doesn't include a ValidationError class, which we want to
|
6
|
-
# raise when model.validate! fails.
|
7
|
-
#
|
8
|
-
# In order to break the least amount of code that uses AM5+, while still
|
9
|
-
# supporting AM4 we use this proxy class that inherits from
|
10
|
-
# AM::ValidationError if it's there, or reimplements it otherwise
|
11
|
-
if defined?(::ActiveModel::ValidationError)
|
12
|
-
class ValidationError < ::ActiveModel::ValidationError; end
|
13
|
-
else
|
14
|
-
class ValidationError < StandardError
|
15
|
-
attr_reader :model
|
16
|
-
|
17
|
-
def initialize(model)
|
18
|
-
@model = model
|
19
|
-
errors = @model.errors.full_messages.join(", ")
|
20
|
-
super("Invalid model: #{errors}")
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
data/lib/fmrest/string_date.rb
DELETED
@@ -1,220 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "date"
|
4
|
-
|
5
|
-
module FmRest
|
6
|
-
# Gotchas:
|
7
|
-
#
|
8
|
-
# 1.
|
9
|
-
#
|
10
|
-
# Date === <StringDate instance> # => false
|
11
|
-
#
|
12
|
-
# The above can affect case conditions, as trying to match a StringDate
|
13
|
-
# with:
|
14
|
-
#
|
15
|
-
# case obj
|
16
|
-
# when Date
|
17
|
-
# ...
|
18
|
-
#
|
19
|
-
# ...will not work.
|
20
|
-
#
|
21
|
-
# Instead one must specify the FmRest::StringDate class:
|
22
|
-
#
|
23
|
-
# case obj
|
24
|
-
# when Date, FmRest::StringDate
|
25
|
-
# ...
|
26
|
-
#
|
27
|
-
# 2.
|
28
|
-
#
|
29
|
-
# StringDate#eql? only matches other strings, not dates.
|
30
|
-
#
|
31
|
-
# This could affect hash indexing when a StringDate is used as a key.
|
32
|
-
#
|
33
|
-
# TODO: Verify the above
|
34
|
-
#
|
35
|
-
# 3.
|
36
|
-
#
|
37
|
-
# StringDate#succ and StringDate#next return a String, despite Date#succ
|
38
|
-
# and Date#next also existing.
|
39
|
-
#
|
40
|
-
# Workaround: Use StringDate#next_day or strdate + 1
|
41
|
-
#
|
42
|
-
# 4.
|
43
|
-
#
|
44
|
-
# StringDate#to_s returns the original string, not the Date string
|
45
|
-
# representation.
|
46
|
-
#
|
47
|
-
# Workaround: Use strdate.to_date.to_s
|
48
|
-
#
|
49
|
-
# 5.
|
50
|
-
#
|
51
|
-
# StringDate#hash returns the hash for the string (important when using
|
52
|
-
# a StringDate as a hash key)
|
53
|
-
#
|
54
|
-
# 6.
|
55
|
-
#
|
56
|
-
# StringDate#as_json returns the string
|
57
|
-
#
|
58
|
-
# Workaround: Use strdate.to_date.as_json
|
59
|
-
#
|
60
|
-
# 7.
|
61
|
-
#
|
62
|
-
# Equality with Date is not reciprocal:
|
63
|
-
#
|
64
|
-
# str_date == date #=> true
|
65
|
-
# date == str_date #=> false
|
66
|
-
#
|
67
|
-
# NOTE: Potential workaround: Inherit StringDate from Date instead of String
|
68
|
-
#
|
69
|
-
# 8.
|
70
|
-
#
|
71
|
-
# Calling string transforming methods (e.g. .upcase) returns a StringDate
|
72
|
-
# instead of a String.
|
73
|
-
#
|
74
|
-
# NOTE: Potential workaround: Inherit StringDate from Date instead of String
|
75
|
-
#
|
76
|
-
class StringDate < String
|
77
|
-
DELEGATE_CLASS = ::Date
|
78
|
-
|
79
|
-
class InvalidDate < ArgumentError; end
|
80
|
-
|
81
|
-
class << self
|
82
|
-
def strptime(str, date_format, *_)
|
83
|
-
begin
|
84
|
-
date = self::DELEGATE_CLASS.strptime(str, date_format)
|
85
|
-
rescue ArgumentError
|
86
|
-
raise InvalidDate
|
87
|
-
end
|
88
|
-
|
89
|
-
new(str, date)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
def initialize(str, date, **str_args)
|
94
|
-
raise ArgumentError, "str must be of class String" unless str.is_a?(String)
|
95
|
-
raise ArgumentError, "date must be of class #{self.class::DELEGATE_CLASS.name}" unless date.is_a?(self.class::DELEGATE_CLASS)
|
96
|
-
|
97
|
-
super(str, **str_args)
|
98
|
-
|
99
|
-
@delegate = date
|
100
|
-
|
101
|
-
freeze
|
102
|
-
end
|
103
|
-
|
104
|
-
def is_a?(klass)
|
105
|
-
klass == ::Date || super
|
106
|
-
end
|
107
|
-
alias_method :kind_of?, :is_a?
|
108
|
-
|
109
|
-
def to_date
|
110
|
-
@delegate
|
111
|
-
end
|
112
|
-
|
113
|
-
def to_datetime
|
114
|
-
@delegate.to_datetime
|
115
|
-
end
|
116
|
-
|
117
|
-
def to_time
|
118
|
-
@delegate.to_time
|
119
|
-
end
|
120
|
-
|
121
|
-
# ActiveSupport method
|
122
|
-
def in_time_zone(*_)
|
123
|
-
@delegate.in_time_zone(*_)
|
124
|
-
end
|
125
|
-
|
126
|
-
def inspect
|
127
|
-
"#<#{self.class.name} #{@delegate.inspect} - #{super}>"
|
128
|
-
end
|
129
|
-
|
130
|
-
def <=>(oth)
|
131
|
-
return @delegate <=> oth if oth.is_a?(::Date) || oth.is_a?(Numeric)
|
132
|
-
super
|
133
|
-
end
|
134
|
-
|
135
|
-
def +(val)
|
136
|
-
return @delegate + val if val.kind_of?(Numeric)
|
137
|
-
super
|
138
|
-
end
|
139
|
-
|
140
|
-
def <<(val)
|
141
|
-
return @delegate << val if val.kind_of?(Numeric)
|
142
|
-
super
|
143
|
-
end
|
144
|
-
|
145
|
-
def ==(oth)
|
146
|
-
return @delegate == oth if oth.kind_of?(::Date) || oth.kind_of?(Numeric)
|
147
|
-
super
|
148
|
-
end
|
149
|
-
alias_method :===, :==
|
150
|
-
|
151
|
-
def upto(oth, &blk)
|
152
|
-
return @delegate.upto(oth, &blk) if oth.kind_of?(::Date) || oth.kind_of?(Numeric)
|
153
|
-
super
|
154
|
-
end
|
155
|
-
|
156
|
-
def between?(a, b)
|
157
|
-
return @delegate.between?(a, b) if [a, b].any? {|o| o.is_a?(::Date) || o.is_a?(Numeric) }
|
158
|
-
super
|
159
|
-
end
|
160
|
-
|
161
|
-
private
|
162
|
-
|
163
|
-
def respond_to_missing?(name, include_private = false)
|
164
|
-
@delegate.respond_to?(name, include_private)
|
165
|
-
end
|
166
|
-
|
167
|
-
def method_missing(method, *args, &block)
|
168
|
-
@delegate.send(method, *args, &block)
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
class StringDateTime < StringDate
|
173
|
-
DELEGATE_CLASS = ::DateTime
|
174
|
-
|
175
|
-
def is_a?(klass)
|
176
|
-
klass == ::DateTime || super
|
177
|
-
end
|
178
|
-
alias_method :kind_of?, :is_a?
|
179
|
-
|
180
|
-
def to_date
|
181
|
-
@delegate.to_date
|
182
|
-
end
|
183
|
-
|
184
|
-
def to_datetime
|
185
|
-
@delegate
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
module StringDateAwareness
|
190
|
-
def _parse(v, *_)
|
191
|
-
if v.is_a?(StringDateTime)
|
192
|
-
return { year: v.year, mon: v.month, mday: v.mday, hour: v.hour, min: v.min, sec: v.sec, sec_fraction: v.sec_fraction, offset: v.offset }
|
193
|
-
end
|
194
|
-
if v.is_a?(StringDate)
|
195
|
-
return { year: v.year, mon: v.month, mday: v.mday }
|
196
|
-
end
|
197
|
-
super
|
198
|
-
end
|
199
|
-
|
200
|
-
def parse(v, *_)
|
201
|
-
if v.is_a?(StringDate)
|
202
|
-
return self == ::DateTime ? v.to_datetime : v.to_date
|
203
|
-
end
|
204
|
-
super
|
205
|
-
end
|
206
|
-
|
207
|
-
# Overriding case equality method so that it returns true for
|
208
|
-
# `FmRest::StringDate` instances
|
209
|
-
#
|
210
|
-
# Calls superclass method
|
211
|
-
#
|
212
|
-
def ===(other)
|
213
|
-
super || other.is_a?(StringDate)
|
214
|
-
end
|
215
|
-
|
216
|
-
def self.enable(classes: [Date, DateTime])
|
217
|
-
classes.each { |klass| klass.singleton_class.prepend(self) }
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
data/lib/fmrest/token_store.rb
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "fmrest/token_store/base"
|
4
|
-
require "active_record"
|
5
|
-
|
6
|
-
module FmRest
|
7
|
-
module TokenStore
|
8
|
-
# Heavily inspired by Moneta's ActiveRecord store:
|
9
|
-
#
|
10
|
-
# https://github.com/minad/moneta/blob/master/lib/moneta/adapters/activerecord.rb
|
11
|
-
#
|
12
|
-
class ActiveRecord < Base
|
13
|
-
DEFAULT_TABLE_NAME = "fmrest_session_tokens".freeze
|
14
|
-
|
15
|
-
@connection_lock = ::Mutex.new
|
16
|
-
class << self
|
17
|
-
attr_reader :connection_lock
|
18
|
-
end
|
19
|
-
|
20
|
-
attr_reader :connection_pool, :model
|
21
|
-
|
22
|
-
delegate :with_connection, to: :connection_pool
|
23
|
-
|
24
|
-
def initialize(options = {})
|
25
|
-
super
|
26
|
-
|
27
|
-
@connection_pool = ::ActiveRecord::Base.connection_pool
|
28
|
-
|
29
|
-
create_table
|
30
|
-
|
31
|
-
@model = Class.new(::ActiveRecord::Base)
|
32
|
-
@model.table_name = table_name
|
33
|
-
end
|
34
|
-
|
35
|
-
def delete(key)
|
36
|
-
model.where(scope: key).delete_all
|
37
|
-
end
|
38
|
-
|
39
|
-
def load(key)
|
40
|
-
model.where(scope: key).pluck(:token).first
|
41
|
-
end
|
42
|
-
|
43
|
-
def store(key, value)
|
44
|
-
record = model.find_or_initialize_by(scope: key)
|
45
|
-
record.token = value
|
46
|
-
record.save!
|
47
|
-
value
|
48
|
-
end
|
49
|
-
|
50
|
-
private
|
51
|
-
|
52
|
-
def create_table
|
53
|
-
with_connection do |conn|
|
54
|
-
return if conn.table_exists?(table_name)
|
55
|
-
|
56
|
-
# Prevent multiple connections from attempting to create the table simultaneously.
|
57
|
-
self.class.connection_lock.synchronize do
|
58
|
-
conn.create_table(table_name, id: false) do |t|
|
59
|
-
t.string :scope, null: false
|
60
|
-
t.string :token, null: false
|
61
|
-
t.datetime :updated_at
|
62
|
-
end
|
63
|
-
conn.add_index(table_name, :scope, unique: true)
|
64
|
-
conn.add_index(table_name, [:scope, :token])
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def table_name
|
70
|
-
options[:table_name] || DEFAULT_TABLE_NAME
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module FmRest
|
4
|
-
module TokenStore
|
5
|
-
class Base
|
6
|
-
attr_reader :options
|
7
|
-
|
8
|
-
def initialize(options = {})
|
9
|
-
@options = options
|
10
|
-
end
|
11
|
-
|
12
|
-
def load(key)
|
13
|
-
raise "Not implemented"
|
14
|
-
end
|
15
|
-
|
16
|
-
def store(key, value)
|
17
|
-
raise "Not implemented"
|
18
|
-
end
|
19
|
-
|
20
|
-
def delete(key)
|
21
|
-
raise "Not implemented"
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "fmrest/token_store/base"
|
4
|
-
|
5
|
-
module FmRest
|
6
|
-
module TokenStore
|
7
|
-
class Memory < Base
|
8
|
-
def initialize(*args)
|
9
|
-
super
|
10
|
-
@tokens = {}
|
11
|
-
end
|
12
|
-
|
13
|
-
def delete(key)
|
14
|
-
@tokens.delete(key)
|
15
|
-
end
|
16
|
-
|
17
|
-
def load(key)
|
18
|
-
@tokens[key]
|
19
|
-
end
|
20
|
-
|
21
|
-
def store(key, value)
|
22
|
-
@tokens[key] = value
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "fmrest/token_store/base"
|
4
|
-
require "moneta"
|
5
|
-
|
6
|
-
module FmRest
|
7
|
-
module TokenStore
|
8
|
-
class Moneta < Base
|
9
|
-
DEFAULT_ADAPTER = :Memory
|
10
|
-
DEFAULT_PREFIX = "fmrest-token:".freeze
|
11
|
-
|
12
|
-
attr_reader :moneta
|
13
|
-
|
14
|
-
# @param options [Hash]
|
15
|
-
# Options to pass to `Moneta.new`
|
16
|
-
# @option options [Symbol] :adapter (:Memory)
|
17
|
-
# The Moneta adapter to use
|
18
|
-
# @option options [String] :prefix (DEFAULT_PREFIX)
|
19
|
-
# The prefix to use for keys
|
20
|
-
def initialize(options = {})
|
21
|
-
options = options.dup
|
22
|
-
super(options)
|
23
|
-
adapter = options.delete(:adapter) || DEFAULT_ADAPTER
|
24
|
-
options[:prefix] ||= DEFAULT_PREFIX
|
25
|
-
@moneta = ::Moneta.new(adapter, options)
|
26
|
-
end
|
27
|
-
|
28
|
-
def load(key)
|
29
|
-
moneta[key]
|
30
|
-
end
|
31
|
-
|
32
|
-
def delete(key)
|
33
|
-
moneta.delete(key)
|
34
|
-
end
|
35
|
-
|
36
|
-
def store(key, value)
|
37
|
-
moneta[key] = value
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "fmrest/token_store/base"
|
4
|
-
require "redis" unless defined?(MockRedis)
|
5
|
-
|
6
|
-
module FmRest
|
7
|
-
module TokenStore
|
8
|
-
class Redis < Base
|
9
|
-
DEFAULT_PREFIX = "fmrest-token:".freeze
|
10
|
-
|
11
|
-
STORE_OPTIONS = [:redis, :prefix].freeze
|
12
|
-
|
13
|
-
def initialize(options = {})
|
14
|
-
super
|
15
|
-
@redis = @options[:redis] || ::Redis.new(options_for_redis)
|
16
|
-
@prefix = @options[:prefix] || DEFAULT_PREFIX
|
17
|
-
end
|
18
|
-
|
19
|
-
def load(key)
|
20
|
-
@redis.get(prefix_key(key))
|
21
|
-
end
|
22
|
-
|
23
|
-
def store(key, value)
|
24
|
-
@redis.set(prefix_key(key), value)
|
25
|
-
value
|
26
|
-
end
|
27
|
-
|
28
|
-
def delete(key)
|
29
|
-
@redis.del(prefix_key(key))
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def options_for_redis
|
35
|
-
@options.dup.tap do |options|
|
36
|
-
STORE_OPTIONS.each { |opt| options.delete(opt) }
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def prefix_key(key)
|
41
|
-
"#{@prefix}#{key}"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|