wcc-contentful 1.2.0 → 1.2.1
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 +4 -4
- data/app/controllers/wcc/contentful/webhook_controller.rb +2 -0
- data/lib/tasks/download_schema.rake +1 -1
- data/lib/wcc/contentful/configuration.rb +31 -18
- data/lib/wcc/contentful/downloads_schema.rb +5 -4
- data/lib/wcc/contentful/engine.rb +2 -4
- data/lib/wcc/contentful/event.rb +2 -3
- data/lib/wcc/contentful/exceptions.rb +2 -3
- data/lib/wcc/contentful/indexed_representation.rb +2 -6
- data/lib/wcc/contentful/instrumentation.rb +2 -1
- data/lib/wcc/contentful/link.rb +1 -3
- data/lib/wcc/contentful/link_visitor.rb +2 -4
- data/lib/wcc/contentful/middleware/store/caching_middleware.rb +4 -8
- data/lib/wcc/contentful/middleware/store.rb +4 -6
- data/lib/wcc/contentful/model_api.rb +1 -3
- data/lib/wcc/contentful/model_builder.rb +5 -4
- data/lib/wcc/contentful/model_methods.rb +10 -12
- data/lib/wcc/contentful/model_singleton_methods.rb +1 -1
- data/lib/wcc/contentful/rich_text/node.rb +1 -3
- data/lib/wcc/contentful/rich_text.rb +1 -1
- data/lib/wcc/contentful/rspec.rb +1 -3
- data/lib/wcc/contentful/simple_client/response.rb +3 -5
- data/lib/wcc/contentful/simple_client.rb +11 -14
- data/lib/wcc/contentful/store/base.rb +5 -5
- data/lib/wcc/contentful/store/cdn_adapter.rb +1 -1
- data/lib/wcc/contentful/store/factory.rb +1 -1
- data/lib/wcc/contentful/store/memory_store.rb +2 -2
- data/lib/wcc/contentful/store/postgres_store.rb +15 -22
- data/lib/wcc/contentful/store/query.rb +2 -2
- data/lib/wcc/contentful/store/rspec_examples/include_param.rb +6 -4
- data/lib/wcc/contentful/store/rspec_examples/operators.rb +1 -1
- data/lib/wcc/contentful/sync_engine.rb +31 -15
- data/lib/wcc/contentful/sys.rb +2 -1
- data/lib/wcc/contentful/test/double.rb +3 -5
- data/lib/wcc/contentful/test/factory.rb +4 -6
- data/lib/wcc/contentful/version.rb +1 -1
- data/lib/wcc/contentful.rb +5 -7
- data/wcc-contentful.gemspec +5 -5
- metadata +8 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 476f7c65f705c14e012e8c2cbb36f68e29782607377b0a4aa9d0c10fb93458da
|
4
|
+
data.tar.gz: 01aeff71919acef51c8d498c63bc42e822ed3c598e7c636f5faf74baeb74c552
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0383a5fe8ef8b042d0a9aca04c964051fc5201b89e702a80b616e5c3b36fd6fa7590d768d178e96f3353c998923fc87458697f5b1112bdd000e6e273fdb07f56'
|
7
|
+
data.tar.gz: 776a6ec463edbcd209d28dd2033d6378ac45e44dd9bca790aefe81ea529c4fa4d0cf6725bd3f67e5c4054f41bd930e9905165f8ccd42f2a9f01b3bc0ac1deaf6
|
@@ -36,6 +36,7 @@ module WCC::Contentful
|
|
36
36
|
def authorize_contentful
|
37
37
|
config = WCC::Contentful.configuration
|
38
38
|
|
39
|
+
# rubocop:disable Style/SoleNestedConditional
|
39
40
|
if config.webhook_username.present? && config.webhook_password.present?
|
40
41
|
unless authenticate_with_http_basic do |u, p|
|
41
42
|
u == config.webhook_username &&
|
@@ -45,6 +46,7 @@ module WCC::Contentful
|
|
45
46
|
return
|
46
47
|
end
|
47
48
|
end
|
49
|
+
# rubocop:enable Style/SoleNestedConditional
|
48
50
|
|
49
51
|
# 'application/vnd.contentful.management.v1+json' is an alias for the 'application/json'
|
50
52
|
# content-type, so 'request.content_type' will give 'application/json'
|
@@ -5,7 +5,7 @@ require 'wcc/contentful/downloads_schema'
|
|
5
5
|
|
6
6
|
namespace :wcc_contentful do
|
7
7
|
desc 'Downloads the schema from the currently configured space and stores it in ' \
|
8
|
-
|
8
|
+
'db/contentful-schema.json'
|
9
9
|
task download_schema: :environment do
|
10
10
|
WCC::Contentful::DownloadsSchema.call
|
11
11
|
end
|
@@ -3,22 +3,24 @@
|
|
3
3
|
# This object contains all the configuration options for the `wcc-contentful` gem.
|
4
4
|
class WCC::Contentful::Configuration
|
5
5
|
ATTRIBUTES = %i[
|
6
|
-
space
|
7
6
|
access_token
|
8
7
|
app_url
|
9
|
-
management_token
|
10
|
-
environment
|
11
|
-
default_locale
|
12
|
-
preview_token
|
13
|
-
webhook_username
|
14
|
-
webhook_password
|
15
|
-
webhook_jobs
|
16
8
|
connection
|
17
9
|
connection_options
|
18
|
-
|
10
|
+
default_locale
|
11
|
+
environment
|
12
|
+
instrumentation_adapter
|
13
|
+
management_token
|
14
|
+
preview_token
|
19
15
|
schema_file
|
16
|
+
space
|
20
17
|
store
|
21
|
-
|
18
|
+
sync_retry_limit
|
19
|
+
sync_retry_wait
|
20
|
+
update_schema_file
|
21
|
+
webhook_jobs
|
22
|
+
webhook_password
|
23
|
+
webhook_username
|
22
24
|
].freeze
|
23
25
|
|
24
26
|
# (required) Sets the Contentful Space ID.
|
@@ -57,6 +59,17 @@ class WCC::Contentful::Configuration
|
|
57
59
|
# to implement a webhook job.
|
58
60
|
attr_accessor :webhook_jobs
|
59
61
|
|
62
|
+
# Sets the maximum number of times that the SyncEngine will retry synchronization
|
63
|
+
# when it detects that the Contentful CDN's cache has not been updated after a webhook.
|
64
|
+
# Default: 2
|
65
|
+
attr_accessor :sync_retry_limit
|
66
|
+
|
67
|
+
# Sets the base ActiveSupport::Duration that the SyncEngine will wait before retrying.
|
68
|
+
# Each subsequent retry uses an exponential backoff, so the second retry will be
|
69
|
+
# after (2 * sync_retry_wait), the third after (4 * sync_retry_wait), etc.
|
70
|
+
# Default: 2.seconds
|
71
|
+
attr_accessor :sync_retry_wait
|
72
|
+
|
60
73
|
# Returns true if the currently configured environment is pointing at `master`.
|
61
74
|
def master?
|
62
75
|
!environment.present?
|
@@ -145,9 +158,7 @@ class WCC::Contentful::Configuration
|
|
145
158
|
# WCC::Contentful::InitializationError if the API cannot be reached.
|
146
159
|
def update_schema_file=(sym)
|
147
160
|
valid_syms = %i[never if_possible if_missing always]
|
148
|
-
unless valid_syms.include?(sym)
|
149
|
-
raise ArgumentError, "update_schema_file must be one of #{valid_syms}"
|
150
|
-
end
|
161
|
+
raise ArgumentError, "update_schema_file must be one of #{valid_syms}" unless valid_syms.include?(sym)
|
151
162
|
|
152
163
|
@update_schema_file = sym
|
153
164
|
end
|
@@ -172,22 +183,24 @@ class WCC::Contentful::Configuration
|
|
172
183
|
attr_accessor :instrumentation_adapter
|
173
184
|
|
174
185
|
def initialize
|
175
|
-
@access_token = ENV
|
176
|
-
@app_url = ENV
|
186
|
+
@access_token = ENV.fetch('CONTENTFUL_ACCESS_TOKEN', nil)
|
187
|
+
@app_url = ENV.fetch('APP_URL', nil)
|
177
188
|
@connection_options = {
|
178
189
|
api_url: 'https://cdn.contentful.com/',
|
179
190
|
preview_api_url: 'https://preview.contentful.com/',
|
180
191
|
management_api_url: 'https://api.contentful.com'
|
181
192
|
}
|
182
|
-
@management_token = ENV
|
183
|
-
@preview_token = ENV
|
184
|
-
@space = ENV
|
193
|
+
@management_token = ENV.fetch('CONTENTFUL_MANAGEMENT_TOKEN', nil)
|
194
|
+
@preview_token = ENV.fetch('CONTENTFUL_PREVIEW_TOKEN', nil)
|
195
|
+
@space = ENV.fetch('CONTENTFUL_SPACE_ID', nil)
|
185
196
|
@default_locale = nil
|
186
197
|
@middleware = []
|
187
198
|
@update_schema_file = :if_possible
|
188
199
|
@schema_file = 'db/contentful-schema.json'
|
189
200
|
@webhook_jobs = []
|
190
201
|
@store_factory = WCC::Contentful::Store::Factory.new(self, :direct)
|
202
|
+
@sync_retry_limit = 3
|
203
|
+
@sync_retry_wait = 1.second
|
191
204
|
end
|
192
205
|
|
193
206
|
# Validates the configuration, raising ArgumentError if anything is wrong. This
|
@@ -36,7 +36,7 @@ class WCC::Contentful::DownloadsSchema
|
|
36
36
|
begin
|
37
37
|
JSON.parse(File.read(@file))
|
38
38
|
rescue JSON::ParserError
|
39
|
-
return true
|
39
|
+
return true # rubocop:disable Lint/NoReturnInBeginEndBlocks
|
40
40
|
end
|
41
41
|
|
42
42
|
existing_cts = contents['contentTypes'].sort_by { |ct| ct.dig('sys', 'id') }
|
@@ -83,13 +83,14 @@ class WCC::Contentful::DownloadsSchema
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def deep_contains_all(expected, actual)
|
86
|
-
|
86
|
+
case expected
|
87
|
+
when Array
|
87
88
|
expected.each_with_index do |val, i|
|
88
89
|
return false unless actual[i]
|
89
90
|
return false unless deep_contains_all(val, actual[i])
|
90
91
|
end
|
91
92
|
true
|
92
|
-
|
93
|
+
when Hash
|
93
94
|
expected.each do |(key, val)|
|
94
95
|
return false unless actual.key?(key)
|
95
96
|
return false unless deep_contains_all(val, actual[key])
|
@@ -107,6 +108,6 @@ class WCC::Contentful::DownloadsSchema
|
|
107
108
|
# only in its treatment of empty arrays in the "validations" field.
|
108
109
|
json_string = json_string.gsub(/\[\n\n\s+\]/, '[]')
|
109
110
|
# contentful-shell also adds a newline at the end.
|
110
|
-
json_string
|
111
|
+
"#{json_string}\n"
|
111
112
|
end
|
112
113
|
end
|
@@ -6,9 +6,7 @@ module WCC::Contentful
|
|
6
6
|
config = WCC::Contentful.configuration
|
7
7
|
|
8
8
|
jobs = []
|
9
|
-
if WCC::Contentful::Services.instance.sync_engine&.should_sync?
|
10
|
-
jobs << WCC::Contentful::SyncEngine::Job
|
11
|
-
end
|
9
|
+
jobs << WCC::Contentful::SyncEngine::Job if WCC::Contentful::Services.instance.sync_engine&.should_sync?
|
12
10
|
jobs.push(*WCC::Contentful.configuration.webhook_jobs)
|
13
11
|
|
14
12
|
jobs.each do |job|
|
@@ -19,7 +17,7 @@ module WCC::Contentful
|
|
19
17
|
job.perform_later(event.to_h)
|
20
18
|
else
|
21
19
|
Rails.logger.error "Misconfigured webhook job: #{job} does not respond to " \
|
22
|
-
|
20
|
+
':perform_later'
|
23
21
|
end
|
24
22
|
rescue StandardError => e
|
25
23
|
warn "Error in job #{job}: #{e}"
|
data/lib/wcc/contentful/event.rb
CHANGED
@@ -23,9 +23,7 @@ module WCC::Contentful::Event
|
|
23
23
|
|
24
24
|
def register(constant)
|
25
25
|
name = constant.try(:type) || constant.name.demodulize
|
26
|
-
unless constant.respond_to?(:new)
|
27
|
-
raise ArgumentError, "Constant #{constant} does not define 'new'"
|
28
|
-
end
|
26
|
+
raise ArgumentError, "Constant #{constant} does not define 'new'" unless constant.respond_to?(:new)
|
29
27
|
|
30
28
|
@event_types ||= {}
|
31
29
|
@event_types[name] = constant
|
@@ -58,6 +56,7 @@ module WCC::Contentful::Event
|
|
58
56
|
attr_reader :sys
|
59
57
|
attr_reader :raw
|
60
58
|
attr_reader :source
|
59
|
+
|
61
60
|
delegate :id, to: :sys
|
62
61
|
delegate :type, to: :sys
|
63
62
|
delegate :created_at, to: :sys
|
@@ -12,8 +12,7 @@ module WCC::Contentful
|
|
12
12
|
# Raised when an entry contains a circular reference and cannot be represented
|
13
13
|
# as a flat tree.
|
14
14
|
class CircularReferenceError < StandardError
|
15
|
-
attr_reader :stack
|
16
|
-
attr_reader :id
|
15
|
+
attr_reader :stack, :id
|
17
16
|
|
18
17
|
def initialize(stack, id)
|
19
18
|
@id = id
|
@@ -25,7 +24,7 @@ module WCC::Contentful
|
|
25
24
|
return super unless stack
|
26
25
|
|
27
26
|
super + "\n " \
|
28
|
-
|
27
|
+
"#{stack.last} points to #{id} which is also it's ancestor\n " +
|
29
28
|
stack.join('->')
|
30
29
|
end
|
31
30
|
end
|
@@ -109,9 +109,7 @@ module WCC::Contentful
|
|
109
109
|
].freeze
|
110
110
|
|
111
111
|
def type=(raw_type)
|
112
|
-
unless TYPES.include?(raw_type)
|
113
|
-
raise ArgumentError, "Unknown type #{raw_type}, expected one of: #{TYPES}"
|
114
|
-
end
|
112
|
+
raise ArgumentError, "Unknown type #{raw_type}, expected one of: #{TYPES}" unless TYPES.include?(raw_type)
|
115
113
|
|
116
114
|
@type = raw_type
|
117
115
|
end
|
@@ -131,9 +129,7 @@ module WCC::Contentful
|
|
131
129
|
|
132
130
|
if raw_type = hash_or_id.delete('type')
|
133
131
|
raw_type = raw_type.to_sym
|
134
|
-
unless TYPES.include?(raw_type)
|
135
|
-
raise ArgumentError, "Unknown type #{raw_type}, expected one of: #{TYPES}"
|
136
|
-
end
|
132
|
+
raise ArgumentError, "Unknown type #{raw_type}, expected one of: #{TYPES}" unless TYPES.include?(raw_type)
|
137
133
|
|
138
134
|
@type = raw_type
|
139
135
|
end
|
@@ -7,11 +7,12 @@ module WCC::Contentful
|
|
7
7
|
def _instrumentation_event_prefix
|
8
8
|
@_instrumentation_event_prefix ||=
|
9
9
|
# WCC::Contentful => contentful.wcc
|
10
|
-
'.' + (is_a?(Class) || is_a?(Module) ? self : self.class)
|
10
|
+
'.' + (is_a?(Class) || is_a?(Module) ? self : self.class) # rubocop:disable Style/StringConcatenation
|
11
11
|
.name.parameterize.split('-').reverse.join('.')
|
12
12
|
end
|
13
13
|
|
14
14
|
attr_writer :_instrumentation
|
15
|
+
|
15
16
|
def _instrumentation
|
16
17
|
# look for per-instance instrumentation then try class level
|
17
18
|
@_instrumentation || self.class._instrumentation
|
data/lib/wcc/contentful/link.rb
CHANGED
@@ -4,9 +4,7 @@
|
|
4
4
|
# It is used internally by the Store layer to compose the resulting resolved hashes.
|
5
5
|
# But you can use it too!
|
6
6
|
class WCC::Contentful::LinkVisitor
|
7
|
-
attr_reader :entry
|
8
|
-
attr_reader :fields
|
9
|
-
attr_reader :depth
|
7
|
+
attr_reader :entry, :fields, :depth
|
10
8
|
|
11
9
|
# @param [Hash] entry The entry hash (resolved or unresolved) to walk
|
12
10
|
# @param [Array<Symbol>] The type of fields to select from the entry tree.
|
@@ -66,7 +64,7 @@ class WCC::Contentful::LinkVisitor
|
|
66
64
|
|
67
65
|
def each_field(field)
|
68
66
|
each_locale(field) do |val, locale|
|
69
|
-
if val
|
67
|
+
if val.is_a?(Array)
|
70
68
|
val.each_with_index do |v, index|
|
71
69
|
yield(v, field, locale, index) unless v.nil?
|
72
70
|
end
|
@@ -36,12 +36,8 @@ module WCC::Contentful::Middleware::Store
|
|
36
36
|
# figure out how to cache the results of a find_by query, ex:
|
37
37
|
# `find_by('slug' => '/about')`
|
38
38
|
def find_by(content_type:, filter: nil, options: nil)
|
39
|
-
if filter&.keys == ['sys.id']
|
40
|
-
|
41
|
-
# We can return just this item. Stores are not required to implement :include option.
|
42
|
-
if found = @cache.read(filter['sys.id'])
|
43
|
-
return found
|
44
|
-
end
|
39
|
+
if filter&.keys == ['sys.id'] && found = @cache.read(filter['sys.id'])
|
40
|
+
return found
|
45
41
|
end
|
46
42
|
|
47
43
|
store.find_by(content_type: content_type, filter: filter, options: options)
|
@@ -79,8 +75,8 @@ module WCC::Contentful::Middleware::Store
|
|
79
75
|
prev = @cache.read(id)
|
80
76
|
return if prev.nil? && LAZILY_CACHEABLE_TYPES.include?(type)
|
81
77
|
|
82
|
-
if (prev_rev = prev&.dig('sys', 'revision')) && (next_rev = json.dig('sys', 'revision'))
|
83
|
-
return prev
|
78
|
+
if (prev_rev = prev&.dig('sys', 'revision')) && (next_rev = json.dig('sys', 'revision')) && (next_rev < prev_rev)
|
79
|
+
return prev
|
84
80
|
end
|
85
81
|
|
86
82
|
# we also set DeletedEntry objects in the cache - no need to go hit the API when we know
|
@@ -96,9 +96,9 @@ module WCC::Contentful::Middleware::Store
|
|
96
96
|
|
97
97
|
def count
|
98
98
|
if middleware.has_select?
|
99
|
-
raise NameError, "Count cannot be determined because the middleware '#{middleware}'" \
|
100
|
-
|
101
|
-
|
99
|
+
raise NameError, "Count cannot be determined because the middleware '#{middleware}' " \
|
100
|
+
"implements the #select? method. Please use '.to_a.count' to count entries that " \
|
101
|
+
'pass the #select? method.'
|
102
102
|
end
|
103
103
|
|
104
104
|
# The wrapped query may get count from the "Total" field in the response,
|
@@ -112,9 +112,7 @@ module WCC::Contentful::Middleware::Store
|
|
112
112
|
result = wrapped_query.to_enum
|
113
113
|
result = result.select { |x| middleware.select?(x) } if middleware.has_select?
|
114
114
|
|
115
|
-
if options && options[:include]
|
116
|
-
result = result.map { |x| middleware.resolve_includes(x, options[:include]) }
|
117
|
-
end
|
115
|
+
result = result.map { |x| middleware.resolve_includes(x, options[:include]) } if options && options[:include]
|
118
116
|
|
119
117
|
result.map { |x| middleware.transform(x) }
|
120
118
|
end
|
@@ -51,9 +51,7 @@ module WCC::Contentful::ModelAPI
|
|
51
51
|
|
52
52
|
file = configuration.schema_file
|
53
53
|
schema_json = JSON.parse(File.read(file))['contentTypes']
|
54
|
-
unless schema_json
|
55
|
-
raise ArgumentError, 'Please give either a JSON array of content types or file to load from'
|
56
|
-
end
|
54
|
+
raise ArgumentError, 'Please give either a JSON array of content types or file to load from' unless schema_json
|
57
55
|
|
58
56
|
@schema = WCC::Contentful::ContentTypeIndexer.from_json_schema(schema_json).types
|
59
57
|
end
|
@@ -61,7 +61,7 @@ module WCC::Contentful
|
|
61
61
|
ct = content_type_from_raw(raw)
|
62
62
|
if ct != typedef.content_type
|
63
63
|
raise ArgumentError, 'Wrong Content Type - ' \
|
64
|
-
|
64
|
+
"'#{raw.dig('sys', 'id')}' is a #{ct}, expected #{typedef.content_type}"
|
65
65
|
end
|
66
66
|
@raw = raw.freeze
|
67
67
|
|
@@ -107,12 +107,13 @@ module WCC::Contentful
|
|
107
107
|
# array fields need to resolve to an empty array when nothing is there
|
108
108
|
raw_value = []
|
109
109
|
end
|
110
|
-
instance_variable_set(
|
110
|
+
instance_variable_set("@#{f.name}", raw_value)
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
114
|
attr_reader :sys
|
115
115
|
attr_reader :raw
|
116
|
+
|
116
117
|
delegate :id, to: :sys
|
117
118
|
delegate :created_at, to: :sys
|
118
119
|
delegate :updated_at, to: :sys
|
@@ -122,11 +123,11 @@ module WCC::Contentful
|
|
122
123
|
# Make a field for each column:
|
123
124
|
typedef.fields.each_value do |f|
|
124
125
|
name = f.name
|
125
|
-
var_name =
|
126
|
+
var_name = "@#{name}"
|
126
127
|
case f.type
|
127
128
|
when :Asset, :Link
|
128
129
|
define_method(name) do
|
129
|
-
val = instance_variable_get(var_name
|
130
|
+
val = instance_variable_get("#{var_name}_resolved")
|
130
131
|
return val if val.present?
|
131
132
|
|
132
133
|
_resolve_field(name)
|
@@ -54,17 +54,15 @@ module WCC::Contentful::ModelMethods
|
|
54
54
|
_instrument 'resolve', id: id, depth: depth, backlinks: backlinked_ids do
|
55
55
|
# use include param to do resolution
|
56
56
|
store.find_by(content_type: self.class.content_type,
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
57
|
+
filter: { 'sys.id' => id },
|
58
|
+
options: context.except(*MODEL_LAYER_CONTEXT_KEYS).merge!({
|
59
|
+
include: [depth, 10].min
|
60
|
+
}))
|
61
61
|
end
|
62
|
-
unless raw
|
63
|
-
raise WCC::Contentful::ResolveError, "Cannot find #{self.class.content_type} with ID #{id}"
|
64
|
-
end
|
62
|
+
raise WCC::Contentful::ResolveError, "Cannot find #{self.class.content_type} with ID #{id}" unless raw
|
65
63
|
|
66
64
|
@raw = raw.freeze
|
67
|
-
links.each { |f| instance_variable_set(
|
65
|
+
links.each { |f| instance_variable_set("@#{f}", raw.dig('fields', f, sys.locale)) }
|
68
66
|
end
|
69
67
|
|
70
68
|
links.each { |f| _resolve_field(f, depth, context, options) }
|
@@ -142,7 +140,7 @@ module WCC::Contentful::ModelMethods
|
|
142
140
|
def _resolve_field(field_name, depth = 1, context = {}, options = {})
|
143
141
|
return if depth <= 0
|
144
142
|
|
145
|
-
var_name =
|
143
|
+
var_name = "@#{field_name}"
|
146
144
|
return unless val = instance_variable_get(var_name)
|
147
145
|
|
148
146
|
context = sys.context.to_h.merge(context)
|
@@ -182,17 +180,17 @@ module WCC::Contentful::ModelMethods
|
|
182
180
|
val = _try_map(val) { |v| load.call(v) }
|
183
181
|
val = val.compact if val.is_a? Array
|
184
182
|
|
185
|
-
instance_variable_set(var_name
|
183
|
+
instance_variable_set("#{var_name}_resolved", val)
|
186
184
|
rescue WCC::Contentful::CircularReferenceError
|
187
185
|
raise unless options[:circular_reference] == :ignore
|
188
186
|
end
|
189
187
|
end
|
190
188
|
|
191
189
|
def _resolved_field?(field_name, depth = 1)
|
192
|
-
var_name =
|
190
|
+
var_name = "@#{field_name}"
|
193
191
|
raw = instance_variable_get(var_name)
|
194
192
|
return true if raw.nil? || (raw.is_a?(Array) && raw.all?(&:nil?))
|
195
|
-
return false unless val = instance_variable_get(var_name
|
193
|
+
return false unless val = instance_variable_get("#{var_name}_resolved")
|
196
194
|
return true if depth <= 1
|
197
195
|
|
198
196
|
return val.resolved?(depth: depth - 1) unless val.is_a? Array
|
@@ -66,7 +66,7 @@ module WCC::Contentful::ModelSingletonMethods
|
|
66
66
|
new(result, options) if result
|
67
67
|
end
|
68
68
|
|
69
|
-
def inherited(subclass)
|
69
|
+
def inherited(subclass) # rubocop:disable Lint/MissingSuper
|
70
70
|
# If another different class is already registered for this content type,
|
71
71
|
# don't auto-register this one.
|
72
72
|
return if model_namespace.registered?(content_type)
|
@@ -37,9 +37,7 @@ module WCC::Contentful::RichText
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def tokenize(raw, context = nil)
|
40
|
-
unless raw['nodeType'] == node_type
|
41
|
-
raise ArgumentError, "Expected '#{node_type}', got '#{raw['nodeType']}'"
|
42
|
-
end
|
40
|
+
raise ArgumentError, "Expected '#{node_type}', got '#{raw['nodeType']}'" unless raw['nodeType'] == node_type
|
43
41
|
|
44
42
|
values =
|
45
43
|
members.map do |symbol|
|
data/lib/wcc/contentful/rspec.rb
CHANGED
@@ -13,9 +13,7 @@ module WCC::Contentful::RSpec
|
|
13
13
|
# stubs the Model API to return that content type for `.find` and `.find_by`
|
14
14
|
# query methods.
|
15
15
|
def contentful_stub(const, **attrs)
|
16
|
-
unless const.respond_to?(:content_type_definition)
|
17
|
-
const = WCC::Contentful::Model.resolve_constant(const.to_s)
|
18
|
-
end
|
16
|
+
const = WCC::Contentful::Model.resolve_constant(const.to_s) unless const.respond_to?(:content_type_definition)
|
19
17
|
instance = contentful_create(const, **attrs)
|
20
18
|
|
21
19
|
# mimic what's going on inside model_singleton_methods.rb
|
@@ -6,9 +6,7 @@ class WCC::Contentful::SimpleClient
|
|
6
6
|
class Response
|
7
7
|
include ::WCC::Contentful::Instrumentation
|
8
8
|
|
9
|
-
attr_reader :raw_response
|
10
|
-
attr_reader :client
|
11
|
-
attr_reader :request
|
9
|
+
attr_reader :raw_response, :client, :request
|
12
10
|
|
13
11
|
delegate :status, to: :raw_response
|
14
12
|
alias_method :code, :status
|
@@ -26,7 +24,7 @@ class WCC::Contentful::SimpleClient
|
|
26
24
|
def error_message
|
27
25
|
parsed_message =
|
28
26
|
begin
|
29
|
-
raw
|
27
|
+
raw['message']
|
30
28
|
rescue JSON::ParserError
|
31
29
|
nil
|
32
30
|
end
|
@@ -105,7 +103,7 @@ class WCC::Contentful::SimpleClient
|
|
105
103
|
|
106
104
|
def includes
|
107
105
|
@includes ||=
|
108
|
-
raw
|
106
|
+
raw['includes']&.each_with_object({}) do |(_t, entries), h|
|
109
107
|
entries.each { |e| h[e.dig('sys', 'id')] = e }
|
110
108
|
end || {}
|
111
109
|
end
|
@@ -24,8 +24,7 @@ module WCC::Contentful
|
|
24
24
|
class SimpleClient
|
25
25
|
include WCC::Contentful::Instrumentation
|
26
26
|
|
27
|
-
attr_reader :api_url
|
28
|
-
attr_reader :space
|
27
|
+
attr_reader :api_url, :space
|
29
28
|
|
30
29
|
# Creates a new SimpleClient with the given configuration.
|
31
30
|
#
|
@@ -41,7 +40,7 @@ module WCC::Contentful
|
|
41
40
|
# @option options [Number] rate_limit_wait_timeout The maximum time to block the thread waiting
|
42
41
|
# on a rate limit response. By default will wait for one 429 and then fail on the second 429.
|
43
42
|
def initialize(api_url:, space:, access_token:, **options)
|
44
|
-
@api_url = URI.join(api_url, '/spaces/', space
|
43
|
+
@api_url = URI.join(api_url, '/spaces/', "#{space}/")
|
45
44
|
@space = space
|
46
45
|
@access_token = access_token
|
47
46
|
|
@@ -57,7 +56,7 @@ module WCC::Contentful
|
|
57
56
|
|
58
57
|
return unless options[:environment].present?
|
59
58
|
|
60
|
-
@api_url = URI.join(@api_url, 'environments/', options[:environment]
|
59
|
+
@api_url = URI.join(@api_url, 'environments/', "#{options[:environment]}/")
|
61
60
|
end
|
62
61
|
|
63
62
|
# performs an HTTP GET request to the specified path within the configured
|
@@ -84,15 +83,13 @@ module WCC::Contentful
|
|
84
83
|
case adapter
|
85
84
|
when nil
|
86
85
|
ADAPTERS.each do |a, spec|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
next
|
92
|
-
end
|
86
|
+
gem(*spec)
|
87
|
+
return load_adapter(a)
|
88
|
+
rescue Gem::LoadError
|
89
|
+
next
|
93
90
|
end
|
94
|
-
raise ArgumentError, 'Unable to load adapter! Please install one of '\
|
95
|
-
|
91
|
+
raise ArgumentError, 'Unable to load adapter! Please install one of ' \
|
92
|
+
"#{ADAPTERS.values.map(&:join).join(',')}"
|
96
93
|
when :faraday
|
97
94
|
require 'faraday'
|
98
95
|
::Faraday.new do |faraday|
|
@@ -104,8 +101,8 @@ module WCC::Contentful
|
|
104
101
|
TyphoeusAdapter.new
|
105
102
|
else
|
106
103
|
unless adapter.respond_to?(:get)
|
107
|
-
raise ArgumentError, "Adapter #{adapter} is not invokeable! Please "\
|
108
|
-
|
104
|
+
raise ArgumentError, "Adapter #{adapter} is not invokeable! Please " \
|
105
|
+
"pass use one of #{ADAPTERS.keys} or create a Faraday-compatible adapter"
|
109
106
|
end
|
110
107
|
adapter
|
111
108
|
end
|
@@ -61,11 +61,11 @@ module WCC::Contentful::Store
|
|
61
61
|
set(json.dig('sys', 'id'), json)
|
62
62
|
end
|
63
63
|
|
64
|
-
if (prev_rev = prev&.dig('sys', 'revision')) &&
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
64
|
+
if (prev_rev = prev&.dig('sys', 'revision')) &&
|
65
|
+
(next_rev = json.dig('sys', 'revision')) &&
|
66
|
+
(next_rev < prev_rev)
|
67
|
+
# Uh oh! we overwrote an entry with a prior revision. Put the previous back.
|
68
|
+
return index(prev)
|
69
69
|
end
|
70
70
|
|
71
71
|
case type
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module WCC::Contentful::Store
|
4
4
|
class CDNAdapter
|
5
5
|
include WCC::Contentful::Store::Interface
|
6
|
-
#
|
6
|
+
# NOTE: CDNAdapter should not instrument store events cause it's not a store.
|
7
7
|
|
8
8
|
attr_writer :client, :preview_client
|
9
9
|
|
@@ -41,8 +41,8 @@ module WCC::Contentful::Store
|
|
41
41
|
SUPPORTED_OPS = %i[eq ne in nin].freeze
|
42
42
|
|
43
43
|
def execute(query)
|
44
|
-
(query.conditions.map(&:op) - SUPPORTED_OPS).
|
45
|
-
raise ArgumentError, "Operator :#{
|
44
|
+
if bad_op = (query.conditions.map(&:op) - SUPPORTED_OPS).first
|
45
|
+
raise ArgumentError, "Operator :#{bad_op} not supported"
|
46
46
|
end
|
47
47
|
|
48
48
|
relation = mutex.with_read_lock { @hash.values }
|
@@ -45,12 +45,9 @@ module WCC::Contentful::Store
|
|
45
45
|
JSON.parse(val) if val
|
46
46
|
end
|
47
47
|
|
48
|
-
if views_need_update?(value, previous_value)
|
49
|
-
|
50
|
-
|
51
|
-
_instrument 'mark_dirty'
|
52
|
-
mutex.with_write_lock { @dirty = true }
|
53
|
-
end
|
48
|
+
if views_need_update?(value, previous_value) && !mutex.with_read_lock { @dirty }
|
49
|
+
_instrument 'mark_dirty'
|
50
|
+
mutex.with_write_lock { @dirty = true }
|
54
51
|
end
|
55
52
|
|
56
53
|
previous_value
|
@@ -105,7 +102,7 @@ module WCC::Contentful::Store
|
|
105
102
|
end
|
106
103
|
end
|
107
104
|
|
108
|
-
logger&.debug(
|
105
|
+
logger&.debug("[PostgresStore] #{statement}\n#{params.inspect}")
|
109
106
|
_instrument 'exec' do
|
110
107
|
@connection_pool.with { |conn| conn.exec(statement, params) }
|
111
108
|
end
|
@@ -231,16 +228,12 @@ module WCC::Contentful::Store
|
|
231
228
|
end
|
232
229
|
|
233
230
|
statement =
|
234
|
-
select_statement
|
235
|
-
" FROM #{table} AS t \n" +
|
236
|
-
joins.join("\n") + "\n" +
|
237
|
-
statement +
|
238
|
-
(limit_statement || '')
|
231
|
+
"#{select_statement} FROM #{table} AS t \n#{joins.join("\n")}\n#{statement}#{limit_statement || ''}"
|
239
232
|
|
240
233
|
[statement, params]
|
241
234
|
end
|
242
235
|
|
243
|
-
def _eq(path, expected, params)
|
236
|
+
def _eq(path, expected, params) # rubocop:disable Layout/LineContinuationLeadingSpace
|
244
237
|
return " AND t.id = $#{push_param(expected, params)}" if path == %w[sys id]
|
245
238
|
|
246
239
|
if path[3] == 'sys'
|
@@ -248,12 +241,12 @@ module WCC::Contentful::Store
|
|
248
241
|
# into it to detect whether it contains `{ "sys": { "id" => expected } }`
|
249
242
|
expected = { 'sys' => { path[4] => expected } }.to_json
|
250
243
|
return ' AND fn_contentful_jsonb_any_to_jsonb_array(t.data->' \
|
251
|
-
|
252
|
-
|
244
|
+
"#{quote_parameter_path(path.take(3))}) @> " \
|
245
|
+
"jsonb_build_array($#{push_param(expected, params)}::jsonb)"
|
253
246
|
end
|
254
247
|
|
255
|
-
" AND t.data->#{quote_parameter_path(path)}" \
|
256
|
-
"
|
248
|
+
" AND t.data->#{quote_parameter_path(path)} " \
|
249
|
+
"@> to_jsonb($#{push_param(expected, params)})"
|
257
250
|
end
|
258
251
|
|
259
252
|
PARAM_TYPES = {
|
@@ -292,7 +285,7 @@ module WCC::Contentful::Store
|
|
292
285
|
def push_join(_path, joins)
|
293
286
|
table_alias = "s#{joins.length}"
|
294
287
|
joins << "JOIN contentful_raw AS #{table_alias} ON " \
|
295
|
-
|
288
|
+
"#{table_alias}.id=ANY(t.links)"
|
296
289
|
table_alias
|
297
290
|
end
|
298
291
|
end
|
@@ -326,8 +319,8 @@ module WCC::Contentful::Store
|
|
326
319
|
end
|
327
320
|
|
328
321
|
def schema_ensured?(conn)
|
329
|
-
result = conn.exec('SELECT version FROM wcc_contentful_schema_version' \
|
330
|
-
|
322
|
+
result = conn.exec('SELECT version FROM wcc_contentful_schema_version ' \
|
323
|
+
'ORDER BY version DESC LIMIT 1')
|
331
324
|
return false if result.num_tuples == 0
|
332
325
|
|
333
326
|
result[0]['version'].to_i >= EXPECTED_VERSION
|
@@ -339,8 +332,8 @@ module WCC::Contentful::Store
|
|
339
332
|
def ensure_schema(conn)
|
340
333
|
result =
|
341
334
|
begin
|
342
|
-
conn.exec('SELECT version FROM wcc_contentful_schema_version' \
|
343
|
-
|
335
|
+
conn.exec('SELECT version FROM wcc_contentful_schema_version ' \
|
336
|
+
'ORDER BY version DESC')
|
344
337
|
rescue PG::UndefinedTable
|
345
338
|
[]
|
346
339
|
end
|
@@ -36,7 +36,7 @@ module WCC::Contentful::Store
|
|
36
36
|
|
37
37
|
FALSE_VALUES = [
|
38
38
|
false, 0,
|
39
|
-
'0', :
|
39
|
+
'0', :'0',
|
40
40
|
'f', :f,
|
41
41
|
'F', :F,
|
42
42
|
'false', :false, # rubocop:disable Lint/BooleanSymbol
|
@@ -237,7 +237,7 @@ module WCC::Contentful::Store
|
|
237
237
|
|
238
238
|
Condition =
|
239
239
|
Struct.new(:path, :op, :expected) do
|
240
|
-
LINK_KEYS = %w[id type linkType].freeze
|
240
|
+
LINK_KEYS = %w[id type linkType].freeze # rubocop:disable Lint/ConstantDefinitionInBlock
|
241
241
|
|
242
242
|
def path_tuples
|
243
243
|
@path_tuples ||=
|
@@ -15,10 +15,12 @@ RSpec.shared_examples 'supports include param' do |feature_set|
|
|
15
15
|
'fields' => {
|
16
16
|
'name' => { 'en-US' => 'root' },
|
17
17
|
'link' => { 'en-US' => make_link_to('deep1') },
|
18
|
-
'links' => {
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
'links' => {
|
19
|
+
'en-US' => [
|
20
|
+
make_link_to('shallow3'),
|
21
|
+
make_link_to('deep2')
|
22
|
+
]
|
23
|
+
}
|
22
24
|
}
|
23
25
|
}
|
24
26
|
end
|
@@ -40,7 +40,7 @@ RSpec.shared_examples 'operators' do |feature_set|
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
supported_operators.each do |op, value|
|
43
|
+
supported_operators.each do |op, value| # rubocop:disable Style/CombinableLoops
|
44
44
|
next unless value
|
45
45
|
|
46
46
|
it_behaves_like "supports :#{op} operator" do
|
@@ -31,15 +31,18 @@ module WCC::Contentful
|
|
31
31
|
(@state&.dup || token_wrapper_factory(nil)).freeze
|
32
32
|
end
|
33
33
|
|
34
|
-
attr_reader :store
|
35
|
-
attr_reader :client
|
34
|
+
attr_reader :store, :client, :options
|
36
35
|
|
37
36
|
def should_sync?
|
38
37
|
store&.index?
|
39
38
|
end
|
40
39
|
|
41
|
-
def initialize(
|
42
|
-
@
|
40
|
+
def initialize(client: nil, store: nil, state: nil, **options)
|
41
|
+
@options = {
|
42
|
+
key: "sync:#{object_id}"
|
43
|
+
}.merge!(options).freeze
|
44
|
+
|
45
|
+
@state_key = @options[:key] || "sync:#{object_id}"
|
43
46
|
@client = client || WCC::Contentful::Services.instance.client
|
44
47
|
@mutex = Mutex.new
|
45
48
|
|
@@ -53,9 +56,7 @@ module WCC::Contentful
|
|
53
56
|
if state
|
54
57
|
@state = token_wrapper_factory(state)
|
55
58
|
raise ArgumentError, ':state param must be a String or Hash' unless @state.is_a? Hash
|
56
|
-
unless @state.dig('sys', 'type') == 'token'
|
57
|
-
raise ArgumentError, ':state param must be of sys.type = "token"'
|
58
|
-
end
|
59
|
+
raise ArgumentError, ':state param must be of sys.type = "token"' unless @state.dig('sys', 'type') == 'token'
|
59
60
|
end
|
60
61
|
raise ArgumentError, 'either :state or :store must be provided' unless @state || @store
|
61
62
|
end
|
@@ -144,8 +145,12 @@ module WCC::Contentful
|
|
144
145
|
return unless sync_engine&.should_sync?
|
145
146
|
|
146
147
|
up_to_id = nil
|
147
|
-
|
148
|
-
|
148
|
+
retry_count = 0
|
149
|
+
if event
|
150
|
+
up_to_id = event[:up_to_id] || event.dig('sys', 'id')
|
151
|
+
retry_count = event[:retry_count] if event[:retry_count]
|
152
|
+
end
|
153
|
+
sync!(up_to_id: up_to_id, retry_count: retry_count)
|
149
154
|
end
|
150
155
|
|
151
156
|
# Calls the Contentful Sync API and updates the configured store with the returned
|
@@ -156,21 +161,32 @@ module WCC::Contentful
|
|
156
161
|
# If we don't find this ID in the sync data, then drop a job to try
|
157
162
|
# the sync again after a few minutes.
|
158
163
|
#
|
159
|
-
def sync!(up_to_id: nil)
|
164
|
+
def sync!(up_to_id: nil, retry_count: 0)
|
160
165
|
id_found, count = sync_engine.next(up_to_id: up_to_id)
|
161
166
|
|
162
167
|
next_sync_token = sync_engine.state['token']
|
163
168
|
|
164
169
|
logger.info "Synced #{count} entries. Next sync token:\n #{next_sync_token}"
|
165
|
-
|
166
|
-
|
167
|
-
|
170
|
+
unless id_found
|
171
|
+
if retry_count >= configuration.sync_retry_limit
|
172
|
+
logger.error "Unable to find item with id '#{up_to_id}' on the Sync API. " \
|
173
|
+
"Abandoning after #{retry_count} retries."
|
174
|
+
else
|
175
|
+
wait = (2**retry_count) * configuration.sync_retry_wait.seconds
|
176
|
+
logger.info "Unable to find item with id '#{up_to_id}' on the Sync API. " \
|
177
|
+
"Retrying after #{wait.inspect} " \
|
178
|
+
"(#{configuration.sync_retry_limit - retry_count} retries remaining)"
|
179
|
+
|
180
|
+
self.class.set(wait: wait)
|
181
|
+
.perform_later(up_to_id: up_to_id, retry_count: retry_count + 1)
|
182
|
+
end
|
183
|
+
end
|
168
184
|
next_sync_token
|
169
185
|
end
|
170
186
|
|
171
|
-
#
|
187
|
+
# Enqueues an ActiveJob job to invoke WCC::Contentful.sync! after a given amount
|
172
188
|
# of time.
|
173
|
-
def sync_later!(up_to_id: nil, wait: 10.
|
189
|
+
def sync_later!(up_to_id: nil, wait: 10.seconds)
|
174
190
|
self.class.set(wait: wait)
|
175
191
|
.perform_later(up_to_id: up_to_id)
|
176
192
|
end
|
data/lib/wcc/contentful/sys.rb
CHANGED
@@ -11,7 +11,7 @@ WCC::Contentful::Sys =
|
|
11
11
|
:revision,
|
12
12
|
:context
|
13
13
|
) do
|
14
|
-
|
14
|
+
# rubocop:disable Lint/ConstantDefinitionInBlock
|
15
15
|
ATTRIBUTES = %i[
|
16
16
|
id
|
17
17
|
type
|
@@ -22,6 +22,7 @@ WCC::Contentful::Sys =
|
|
22
22
|
revision
|
23
23
|
context
|
24
24
|
].freeze
|
25
|
+
# rubocop:enable Lint/ConstantDefinitionInBlock
|
25
26
|
|
26
27
|
undef []=
|
27
28
|
ATTRIBUTES.each { |a| __send__(:undef_method, "#{a}=") }
|
@@ -8,9 +8,7 @@ module WCC::Contentful::Test::Double
|
|
8
8
|
# All attributes that are known to be required fields on the content type
|
9
9
|
# will return a default value based on the field type.
|
10
10
|
def contentful_double(const, **attrs)
|
11
|
-
unless const.respond_to?(:content_type_definition)
|
12
|
-
const = WCC::Contentful::Model.resolve_constant(const.to_s)
|
13
|
-
end
|
11
|
+
const = WCC::Contentful::Model.resolve_constant(const.to_s) unless const.respond_to?(:content_type_definition)
|
14
12
|
attrs.symbolize_keys!
|
15
13
|
|
16
14
|
bad_attrs = attrs.reject { |a| const.instance_methods.include?(a) }
|
@@ -45,7 +43,7 @@ module WCC::Contentful::Test::Double
|
|
45
43
|
sys: {
|
46
44
|
type: 'Link',
|
47
45
|
linkType: 'Space',
|
48
|
-
id: ENV
|
46
|
+
id: ENV.fetch('CONTENTFUL_SPACE_ID', nil)
|
49
47
|
}
|
50
48
|
},
|
51
49
|
id: SecureRandom.urlsafe_base64,
|
@@ -62,7 +60,7 @@ module WCC::Contentful::Test::Double
|
|
62
60
|
revision: rand(100),
|
63
61
|
locale: 'en-US'
|
64
62
|
},
|
65
|
-
fields: attrs.
|
63
|
+
fields: attrs.transform_values { |v| { 'en-US' => v } }
|
66
64
|
}
|
67
65
|
|
68
66
|
double(attrs)
|
@@ -8,9 +8,7 @@ module WCC::Contentful::Test::Factory
|
|
8
8
|
# All attributes that are known to be required fields on the content type
|
9
9
|
# will return a default value based on the field type.
|
10
10
|
def contentful_create(const, context = nil, **attrs)
|
11
|
-
unless const.respond_to?(:content_type_definition)
|
12
|
-
const = WCC::Contentful::Model.resolve_constant(const.to_s)
|
13
|
-
end
|
11
|
+
const = WCC::Contentful::Model.resolve_constant(const.to_s) unless const.respond_to?(:content_type_definition)
|
14
12
|
attrs = attrs.transform_keys { |a| a.to_s.camelize(:lower) }
|
15
13
|
|
16
14
|
id = attrs.delete('id')
|
@@ -59,7 +57,7 @@ module WCC::Contentful::Test::Factory
|
|
59
57
|
sys: {
|
60
58
|
type: 'Link',
|
61
59
|
linkType: 'Space',
|
62
|
-
id: ENV
|
60
|
+
id: ENV.fetch('CONTENTFUL_SPACE_ID', nil)
|
63
61
|
}
|
64
62
|
},
|
65
63
|
id: id || SecureRandom.urlsafe_base64,
|
@@ -86,8 +84,8 @@ module WCC::Contentful::Test::Factory
|
|
86
84
|
end
|
87
85
|
|
88
86
|
def contentful_fields(model)
|
89
|
-
WCC::Contentful::Test::Attributes.defaults(model).
|
90
|
-
|
87
|
+
WCC::Contentful::Test::Attributes.defaults(model).transform_values do |v|
|
88
|
+
{ 'en-US' => v }
|
91
89
|
end
|
92
90
|
end
|
93
91
|
|
data/lib/wcc/contentful.rb
CHANGED
@@ -48,7 +48,7 @@ module WCC::Contentful
|
|
48
48
|
def logger
|
49
49
|
return Rails.logger if defined?(Rails)
|
50
50
|
|
51
|
-
@logger ||= Logger.new(
|
51
|
+
@logger ||= Logger.new($stderr)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -82,7 +82,7 @@ module WCC::Contentful
|
|
82
82
|
|
83
83
|
if configuration.update_schema_file == :always ||
|
84
84
|
(configuration.update_schema_file == :if_possible && Services.instance.management_client) ||
|
85
|
-
configuration.update_schema_file == :if_missing && !File.exist?(configuration.schema_file)
|
85
|
+
(configuration.update_schema_file == :if_missing && !File.exist?(configuration.schema_file))
|
86
86
|
|
87
87
|
begin
|
88
88
|
downloader = WCC::Contentful::DownloadsSchema.new
|
@@ -96,9 +96,7 @@ module WCC::Contentful
|
|
96
96
|
|
97
97
|
content_types =
|
98
98
|
begin
|
99
|
-
if File.exist?(configuration.schema_file)
|
100
|
-
JSON.parse(File.read(configuration.schema_file))['contentTypes']
|
101
|
-
end
|
99
|
+
JSON.parse(File.read(configuration.schema_file))['contentTypes'] if File.exist?(configuration.schema_file)
|
102
100
|
rescue JSON::ParserError
|
103
101
|
WCC::Contentful.logger.warn("Schema file invalid, ignoring it: #{configuration.schema_file}")
|
104
102
|
nil
|
@@ -119,8 +117,8 @@ module WCC::Contentful
|
|
119
117
|
end
|
120
118
|
|
121
119
|
unless content_types
|
122
|
-
raise InitializationError, 'Unable to load content types from schema file or API!' \
|
123
|
-
|
120
|
+
raise InitializationError, 'Unable to load content types from schema file or API! ' \
|
121
|
+
'Check your access token and space ID.'
|
124
122
|
end
|
125
123
|
|
126
124
|
# Set the schema on the default WCC::Contentful::Model
|
data/wcc-contentful.gemspec
CHANGED
@@ -6,7 +6,7 @@ require 'wcc/contentful/version'
|
|
6
6
|
|
7
7
|
doc_version = Gem::Version.new(WCC::Contentful::VERSION).release.to_s.sub(/\.\d+$/, '')
|
8
8
|
|
9
|
-
# rubocop:disable
|
9
|
+
# rubocop:disable Layout/LineLength
|
10
10
|
Gem::Specification.new do |spec|
|
11
11
|
spec.name = 'wcc-contentful'
|
12
12
|
spec.version = WCC::Contentful::VERSION
|
@@ -19,10 +19,11 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.license = 'MIT'
|
20
20
|
|
21
21
|
spec.metadata = {
|
22
|
-
'documentation_uri' => "https://watermarkchurch.github.io/wcc-contentful/#{doc_version}/wcc-contentful"
|
22
|
+
'documentation_uri' => "https://watermarkchurch.github.io/wcc-contentful/#{doc_version}/wcc-contentful",
|
23
|
+
'rubygems_mfa_required' => 'true'
|
23
24
|
}
|
24
25
|
|
25
|
-
spec.required_ruby_version = '>= 2.
|
26
|
+
spec.required_ruby_version = '>= 2.7'
|
26
27
|
|
27
28
|
spec.files = Dir['app/**/*', 'config/**/*', 'lib/**/*'] +
|
28
29
|
%w[Rakefile README.md wcc-contentful.gemspec]
|
@@ -38,7 +39,6 @@ Gem::Specification.new do |spec|
|
|
38
39
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
39
40
|
spec.add_development_dependency 'rspec-instrumentation-matcher'
|
40
41
|
spec.add_development_dependency 'rspec_junit_formatter', '~> 0.4.1'
|
41
|
-
spec.add_development_dependency 'rubocop', '0.68'
|
42
42
|
spec.add_development_dependency 'simplecov', '~> 0.16.1'
|
43
43
|
spec.add_development_dependency 'vcr', '~> 5.0'
|
44
44
|
spec.add_development_dependency 'webmock', '~> 3.0'
|
@@ -68,4 +68,4 @@ Gem::Specification.new do |spec|
|
|
68
68
|
spec.add_dependency 'wcc-base', '~> 0.3.1'
|
69
69
|
spec.add_dependency 'wisper', '~> 2.0.0'
|
70
70
|
end
|
71
|
-
# rubocop:enable
|
71
|
+
# rubocop:enable Layout/LineLength
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wcc-contentful
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Watermark Dev
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-08-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: byebug
|
@@ -136,20 +136,6 @@ dependencies:
|
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: 0.4.1
|
139
|
-
- !ruby/object:Gem::Dependency
|
140
|
-
name: rubocop
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - '='
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: '0.68'
|
146
|
-
type: :development
|
147
|
-
prerelease: false
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - '='
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: '0.68'
|
153
139
|
- !ruby/object:Gem::Dependency
|
154
140
|
name: simplecov
|
155
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -504,7 +490,8 @@ licenses:
|
|
504
490
|
- MIT
|
505
491
|
metadata:
|
506
492
|
documentation_uri: https://watermarkchurch.github.io/wcc-contentful/1.2/wcc-contentful
|
507
|
-
|
493
|
+
rubygems_mfa_required: 'true'
|
494
|
+
post_install_message:
|
508
495
|
rdoc_options: []
|
509
496
|
require_paths:
|
510
497
|
- lib
|
@@ -512,15 +499,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
512
499
|
requirements:
|
513
500
|
- - ">="
|
514
501
|
- !ruby/object:Gem::Version
|
515
|
-
version: '2.
|
502
|
+
version: '2.7'
|
516
503
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
517
504
|
requirements:
|
518
505
|
- - ">="
|
519
506
|
- !ruby/object:Gem::Version
|
520
507
|
version: '0'
|
521
508
|
requirements: []
|
522
|
-
rubygems_version: 3.
|
523
|
-
signing_key:
|
509
|
+
rubygems_version: 3.1.6
|
510
|
+
signing_key:
|
524
511
|
specification_version: 4
|
525
512
|
summary: '[](https://rubygems.org/gems/wcc-contentful)
|
526
513
|
[](https://circleci.com/gh/watermarkchurch/wcc-contentful)
|