wcc-contentful 0.2.2 → 0.3.0.pre.rc
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/.rspec +0 -1
- data/README.md +181 -8
- data/app/controllers/wcc/contentful/webhook_controller.rb +42 -2
- data/app/jobs/wcc/contentful/delayed_sync_job.rb +52 -3
- data/app/jobs/wcc/contentful/webhook_enable_job.rb +43 -0
- data/bin/console +4 -3
- data/bin/rails +2 -0
- data/config/initializers/mime_types.rb +10 -1
- data/lib/wcc/contentful.rb +14 -142
- data/lib/wcc/contentful/client_ext.rb +17 -4
- data/lib/wcc/contentful/configuration.rb +25 -84
- data/lib/wcc/contentful/engine.rb +19 -0
- data/lib/wcc/contentful/exceptions.rb +25 -28
- data/lib/wcc/contentful/graphql.rb +0 -1
- data/lib/wcc/contentful/graphql/types.rb +1 -1
- data/lib/wcc/contentful/helpers.rb +3 -2
- data/lib/wcc/contentful/indexed_representation.rb +6 -0
- data/lib/wcc/contentful/model.rb +68 -34
- data/lib/wcc/contentful/model_builder.rb +65 -67
- data/lib/wcc/contentful/model_methods.rb +189 -0
- data/lib/wcc/contentful/model_singleton_methods.rb +83 -0
- data/lib/wcc/contentful/services.rb +146 -0
- data/lib/wcc/contentful/simple_client.rb +35 -33
- data/lib/wcc/contentful/simple_client/http_adapter.rb +9 -0
- data/lib/wcc/contentful/simple_client/management.rb +81 -0
- data/lib/wcc/contentful/simple_client/response.rb +61 -37
- data/lib/wcc/contentful/simple_client/typhoeus_adapter.rb +12 -0
- data/lib/wcc/contentful/store.rb +45 -18
- data/lib/wcc/contentful/store/base.rb +128 -8
- data/lib/wcc/contentful/store/cdn_adapter.rb +92 -22
- data/lib/wcc/contentful/store/lazy_cache_store.rb +94 -9
- data/lib/wcc/contentful/store/memory_store.rb +13 -8
- data/lib/wcc/contentful/store/postgres_store.rb +44 -11
- data/lib/wcc/contentful/sys.rb +28 -0
- data/lib/wcc/contentful/version.rb +1 -1
- data/wcc-contentful.gemspec +3 -9
- metadata +87 -107
- data/.circleci/config.yml +0 -51
- data/.gitignore +0 -26
- data/.rubocop.yml +0 -243
- data/.rubocop_todo.yml +0 -13
- data/.travis.yml +0 -5
- data/CHANGELOG.md +0 -45
- data/CODE_OF_CONDUCT.md +0 -74
- data/Guardfile +0 -58
- data/LICENSE.txt +0 -21
- data/Rakefile +0 -8
- data/lib/generators/wcc/USAGE +0 -24
- data/lib/generators/wcc/model_generator.rb +0 -90
- data/lib/generators/wcc/templates/.keep +0 -0
- data/lib/generators/wcc/templates/Procfile +0 -3
- data/lib/generators/wcc/templates/contentful_shell_wrapper +0 -385
- data/lib/generators/wcc/templates/menu/generated_add_menus.ts +0 -90
- data/lib/generators/wcc/templates/menu/models/menu.rb +0 -23
- data/lib/generators/wcc/templates/menu/models/menu_button.rb +0 -23
- data/lib/generators/wcc/templates/page/generated_add_pages.ts +0 -50
- data/lib/generators/wcc/templates/page/models/page.rb +0 -23
- data/lib/generators/wcc/templates/release +0 -9
- data/lib/generators/wcc/templates/wcc_contentful.rb +0 -17
- data/lib/wcc/contentful/model/menu.rb +0 -7
- data/lib/wcc/contentful/model/menu_button.rb +0 -15
- data/lib/wcc/contentful/model/page.rb +0 -8
- data/lib/wcc/contentful/model/redirect.rb +0 -19
- data/lib/wcc/contentful/model_validators.rb +0 -115
- data/lib/wcc/contentful/model_validators/dsl.rb +0 -165
data/lib/wcc/contentful.rb
CHANGED
@@ -8,82 +8,39 @@ require 'active_support/core_ext/object'
|
|
8
8
|
require 'wcc/contentful/configuration'
|
9
9
|
require 'wcc/contentful/exceptions'
|
10
10
|
require 'wcc/contentful/helpers'
|
11
|
+
require 'wcc/contentful/services'
|
11
12
|
require 'wcc/contentful/simple_client'
|
12
13
|
require 'wcc/contentful/store'
|
13
14
|
require 'wcc/contentful/content_type_indexer'
|
14
|
-
require 'wcc/contentful/model_validators'
|
15
15
|
require 'wcc/contentful/model'
|
16
|
+
require 'wcc/contentful/model_methods'
|
17
|
+
require 'wcc/contentful/model_singleton_methods'
|
16
18
|
require 'wcc/contentful/model_builder'
|
17
19
|
|
18
|
-
##
|
19
20
|
# The root namespace of the wcc-contentful gem
|
20
21
|
#
|
21
22
|
# Initialize the gem with the `configure` and `init` methods inside your
|
22
23
|
# initializer.
|
23
24
|
module WCC::Contentful
|
24
25
|
class << self
|
25
|
-
##
|
26
26
|
# Gets the current configuration, after calling WCC::Contentful.configure
|
27
27
|
attr_reader :configuration
|
28
28
|
|
29
|
-
|
30
|
-
# Gets the sync token that was returned by the Contentful CDN after the most
|
31
|
-
# recent invocation of WCC::Contentful.sync!
|
32
|
-
attr_reader :next_sync_token
|
29
|
+
attr_reader :types
|
33
30
|
end
|
34
31
|
|
35
|
-
##
|
36
|
-
# Gets a {CDN Client}[rdoc-ref:WCC::Contentful::SimpleClient::Cdn] which provides
|
37
|
-
# methods for getting and paging raw JSON data from the Contentful CDN.
|
38
|
-
def self.client(preview: false)
|
39
|
-
if preview
|
40
|
-
configuration&.preview_client
|
41
|
-
else
|
42
|
-
configuration&.client
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
##
|
47
|
-
# Gets the data-store which executes the queries run against the dynamic
|
48
|
-
# models in the WCC::Contentful::Model namespace.
|
49
|
-
# This is one of the following based on the configured content_delivery method:
|
50
|
-
#
|
51
|
-
# [:direct] an instance of WCC::Contentful::Store::CDNAdapter with a
|
52
|
-
# {CDN Client}[rdoc-ref:WCC::Contentful::SimpleClient::Cdn] to access the CDN.
|
53
|
-
#
|
54
|
-
# [:lazy_sync] an instance of WCC::Contentful::Store::LazyCacheStore
|
55
|
-
# with the configured ActiveSupport::Cache implementation and a
|
56
|
-
# {CDN Client}[rdoc-ref:WCC::Contentful::SimpleClient::Cdn] for when data
|
57
|
-
# cannot be found in the cache.
|
58
|
-
#
|
59
|
-
# [:eager_sync] an instance of the configured Store type, defined by
|
60
|
-
# WCC::Contentful::Configuration.sync_store
|
61
|
-
#
|
62
|
-
def self.store
|
63
|
-
WCC::Contentful::Model.store
|
64
|
-
end
|
65
|
-
|
66
|
-
def self.preview_store
|
67
|
-
WCC::Contentful::Model.preview_store
|
68
|
-
end
|
69
|
-
|
70
|
-
##
|
71
32
|
# Configures the WCC::Contentful gem to talk to a Contentful space.
|
72
33
|
# This must be called first in your initializer, before #init! or accessing the
|
73
34
|
# client.
|
74
35
|
def self.configure
|
75
36
|
@configuration ||= Configuration.new
|
76
|
-
@next_sync_token = nil
|
77
37
|
yield(configuration)
|
78
38
|
|
79
39
|
configuration.validate!
|
80
40
|
|
81
|
-
configuration.configure_contentful
|
82
|
-
|
83
41
|
configuration
|
84
42
|
end
|
85
43
|
|
86
|
-
##
|
87
44
|
# Initializes the WCC::Contentful model-space and backing store.
|
88
45
|
# This populates the WCC::Contentful::Model namespace with Ruby classes
|
89
46
|
# that represent content types in the configured Contentful space.
|
@@ -91,24 +48,17 @@ module WCC::Contentful
|
|
91
48
|
# These content types can be queried directly:
|
92
49
|
# WCC::Contentful::Model::Page.find('1xab...')
|
93
50
|
# Or you can inherit from them in your own app:
|
94
|
-
# class Page < WCC::Contentful::Model
|
51
|
+
# class Page < WCC::Contentful::Model::Page; end
|
95
52
|
# Page.find_by(slug: 'about-us')
|
96
53
|
def self.init!
|
97
54
|
raise ArgumentError, 'Please first call WCC:Contentful.configure' if configuration.nil?
|
98
|
-
@mutex ||= Mutex.new
|
99
|
-
|
100
|
-
use_preview_client = false
|
101
|
-
# we want as much as possible the raw JSON from the API
|
102
|
-
content_types_resp =
|
103
|
-
if configuration.management_client
|
104
|
-
configuration.management_client.content_types(limit: 1000)
|
105
|
-
else
|
106
|
-
configuration.client.content_types(limit: 1000)
|
107
|
-
end
|
108
55
|
|
109
|
-
|
56
|
+
# we want as much as possible the raw JSON from the API so use the management
|
57
|
+
# client if possible
|
58
|
+
client = Services.instance.management_client ||
|
59
|
+
Services.instance.client
|
110
60
|
|
111
|
-
@content_types =
|
61
|
+
@content_types = client.content_types(limit: 1000).items
|
112
62
|
|
113
63
|
indexer =
|
114
64
|
ContentTypeIndexer.new.tap do |ixr|
|
@@ -116,92 +66,14 @@ module WCC::Contentful
|
|
116
66
|
end
|
117
67
|
@types = indexer.types
|
118
68
|
|
119
|
-
|
120
|
-
store = configuration.store(preview: false)
|
121
|
-
WCC::Contentful::Model.store = store
|
122
|
-
preview_store = configuration.store(preview: use_preview_client)
|
123
|
-
WCC::Contentful::Model.preview_store = preview_store
|
124
|
-
else
|
125
|
-
store = configuration.store(preview: use_preview_client)
|
126
|
-
WCC::Contentful::Model.store = store
|
127
|
-
end
|
128
|
-
|
69
|
+
store = Services.instance.store
|
129
70
|
if store.respond_to?(:index)
|
130
|
-
|
131
|
-
|
71
|
+
# Drop an initial sync
|
72
|
+
WCC::Contentful::DelayedSyncJob.perform_later
|
132
73
|
end
|
133
74
|
|
134
75
|
WCC::Contentful::ModelBuilder.new(@types).build_models
|
135
76
|
|
136
|
-
|
137
|
-
@types.each_value do |t|
|
138
|
-
file = File.dirname(__FILE__) + "/contentful/model/#{t.name.underscore}.rb"
|
139
|
-
require file if File.exist?(file)
|
140
|
-
end
|
77
|
+
require_relative 'contentful/client_ext' if defined?(::Contentful)
|
141
78
|
end
|
142
|
-
|
143
|
-
##
|
144
|
-
# Runs validations over the content types returned from the Contentful API.
|
145
|
-
# Validations are configured on predefined model classes using the
|
146
|
-
# `validate_field` directive. Example:
|
147
|
-
# validate_field :top_button, :Link, :optional, link_to: 'menuButton'
|
148
|
-
# This results in a WCC::Contentful::ValidationError
|
149
|
-
# if the 'topButton' field in the 'menu' content type is not a link.
|
150
|
-
def self.validate_models!
|
151
|
-
# Ensure application models are loaded before we validate
|
152
|
-
Dir[Rails.root.join('app/models/**/*.rb')].each { |file| require file } if defined?(Rails)
|
153
|
-
|
154
|
-
content_types = WCC::Contentful::ModelValidators.transform_content_types_for_validation(
|
155
|
-
@content_types
|
156
|
-
)
|
157
|
-
errors = WCC::Contentful::Model.schema.call(content_types)
|
158
|
-
raise WCC::Contentful::ValidationError, errors.errors unless errors.success?
|
159
|
-
end
|
160
|
-
|
161
|
-
##
|
162
|
-
# Calls the Contentful Sync API and updates the configured store with the returned
|
163
|
-
# data.
|
164
|
-
#
|
165
|
-
# up_to_id: An ID that we know has changed and should come back from the sync.
|
166
|
-
# If we don't find this ID in the sync data, then drop a job to try
|
167
|
-
# the sync again after a few minutes.
|
168
|
-
#
|
169
|
-
def self.sync!(up_to_id: nil)
|
170
|
-
return unless store.respond_to?(:index)
|
171
|
-
|
172
|
-
@mutex.synchronize do
|
173
|
-
sync_resp = client.sync(sync_token: next_sync_token)
|
174
|
-
|
175
|
-
id_found = up_to_id.nil?
|
176
|
-
|
177
|
-
sync_resp.items.each do |item|
|
178
|
-
id = item.dig('sys', 'id')
|
179
|
-
id_found ||= id == up_to_id
|
180
|
-
store.index(item)
|
181
|
-
end
|
182
|
-
store.set("sync:#{configuration.space}:token", sync_resp.next_sync_token)
|
183
|
-
@next_sync_token = sync_resp.next_sync_token
|
184
|
-
|
185
|
-
unless id_found
|
186
|
-
raise SyncError, "ID '#{up_to_id}' did not come back via sync." unless defined?(Rails)
|
187
|
-
sync_later!(up_to_id: up_to_id)
|
188
|
-
end
|
189
|
-
next_sync_token
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
##
|
194
|
-
# Drops an ActiveJob job to invoke WCC::Contentful.sync! after a given amount
|
195
|
-
# of time.
|
196
|
-
def self.sync_later!(up_to_id: nil, wait: 10.minutes)
|
197
|
-
raise NotImplementedError, 'Cannot sync_later! outside of a Rails app' unless defined?(Rails)
|
198
|
-
|
199
|
-
WCC::Contentful::DelayedSyncJob.set(wait: wait).perform_later(up_to_id)
|
200
|
-
end
|
201
|
-
|
202
|
-
# TODO: https://zube.io/watermarkchurch/development/c/2234 init graphql
|
203
|
-
# def self.init_graphql!
|
204
|
-
# require 'wcc/contentful/graphql'
|
205
|
-
# etc...
|
206
|
-
# end
|
207
79
|
end
|
@@ -5,11 +5,24 @@ class Contentful::Client
|
|
5
5
|
alias_method :old_get_http, :get_http
|
6
6
|
end
|
7
7
|
|
8
|
+
def self.adapter
|
9
|
+
@adapter ||=
|
10
|
+
WCC::Contentful::SimpleClient.load_adapter(WCC::Contentful.configuration.http_adapter) ||
|
11
|
+
->(url, query, headers, proxy) { old_get_http(url, query, headers, proxy) }
|
12
|
+
end
|
13
|
+
|
8
14
|
def self.get_http(url, query, headers = {}, proxy = {})
|
9
|
-
if
|
10
|
-
|
11
|
-
else
|
12
|
-
old_get_http(url, query, headers, proxy)
|
15
|
+
if environment = WCC::Contentful.configuration.environment
|
16
|
+
url = rewrite_to_environment(url, environment)
|
13
17
|
end
|
18
|
+
|
19
|
+
adapter.call(url, query, headers, proxy)
|
20
|
+
end
|
21
|
+
|
22
|
+
REWRITE_REGEXP = /^(https?\:\/\/(?:\w+)\.contentful\.com\/spaces\/[^\/]+\/)(?!environments)(.+)$/
|
23
|
+
def self.rewrite_to_environment(url, environment)
|
24
|
+
return url unless m = REWRITE_REGEXP.match(url)
|
25
|
+
|
26
|
+
File.join(m[1], 'environments', environment, m[2])
|
14
27
|
end
|
15
28
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
class WCC::Contentful::Configuration
|
4
4
|
ATTRIBUTES = %i[
|
5
5
|
access_token
|
6
|
+
app_url
|
6
7
|
management_token
|
7
8
|
space
|
8
9
|
environment
|
@@ -13,23 +14,28 @@ class WCC::Contentful::Configuration
|
|
13
14
|
sync_cache_store
|
14
15
|
webhook_username
|
15
16
|
webhook_password
|
17
|
+
webhook_jobs
|
16
18
|
].freeze
|
17
19
|
attr_accessor(*ATTRIBUTES)
|
18
20
|
|
19
|
-
|
21
|
+
# Returns true if the currently configured environment is pointing at `master`.
|
22
|
+
def master?
|
23
|
+
!environment.present?
|
24
|
+
end
|
25
|
+
|
20
26
|
# Defines the method by which content is downloaded from the Contentful CDN.
|
21
27
|
#
|
22
28
|
# [:direct] `config.content_delivery = :direct`
|
23
29
|
# with the `:direct` method, all queries result in web requests to
|
24
30
|
# 'https://cdn.contentful.com' via the
|
25
|
-
# {
|
31
|
+
# {WCC::Contentful::SimpleClient::Cdn SimpleClient}
|
26
32
|
#
|
27
33
|
# [:eager_sync] `config.content_delivery = :eager_sync, [sync_store], [options]`
|
28
34
|
# with the `:eager_sync` method, the entire content of the Contentful
|
29
35
|
# space is downloaded locally and stored in the
|
30
|
-
# {
|
31
|
-
# to periodically call `WCC::Contentful.sync!` to keep the store
|
32
|
-
# Alternatively, the provided {
|
36
|
+
# {WCC::Contentful::Services#store configured store}. The application is
|
37
|
+
# responsible to periodically call `WCC::Contentful.sync!` to keep the store
|
38
|
+
# updated. Alternatively, the provided {WCC::Contentful::Engine Engine}
|
33
39
|
# can be mounted to receive a webhook from the Contentful space
|
34
40
|
# on publish events:
|
35
41
|
# mount WCC::Contentful::Engine, at: '/wcc/contentful'
|
@@ -51,6 +57,7 @@ class WCC::Contentful::Configuration
|
|
51
57
|
|
52
58
|
WCC::Contentful::Store::Factory.new(
|
53
59
|
self,
|
60
|
+
nil,
|
54
61
|
cd,
|
55
62
|
cd_params
|
56
63
|
).validate!
|
@@ -59,31 +66,18 @@ class WCC::Contentful::Configuration
|
|
59
66
|
@content_delivery_params = cd_params
|
60
67
|
end
|
61
68
|
|
62
|
-
|
63
|
-
# Initializes the configured Sync Store.
|
64
|
-
def store(preview: false)
|
65
|
-
if preview
|
66
|
-
@preview_store ||= WCC::Contentful::Store::Factory.new(
|
67
|
-
self,
|
68
|
-
:direct,
|
69
|
-
[{ preview: preview }]
|
70
|
-
).build_sync_store
|
71
|
-
else
|
72
|
-
@store ||= WCC::Contentful::Store::Factory.new(
|
73
|
-
self,
|
74
|
-
@content_delivery,
|
75
|
-
@content_delivery_params
|
76
|
-
).build_sync_store
|
77
|
-
end
|
78
|
-
end
|
69
|
+
attr_reader :content_delivery_params
|
79
70
|
|
80
|
-
##
|
81
71
|
# Directly sets the adapter layer for communicating with Contentful
|
82
72
|
def store=(value)
|
83
73
|
@content_delivery = :custom
|
84
|
-
|
74
|
+
store, *cd_params = value
|
75
|
+
@store = store
|
76
|
+
@content_delivery_params = cd_params
|
85
77
|
end
|
86
78
|
|
79
|
+
attr_reader :store
|
80
|
+
|
87
81
|
# Sets the adapter which is used to make HTTP requests.
|
88
82
|
# If left unset, the gem attempts to load either 'http' or 'typhoeus'.
|
89
83
|
# You can pass your own adapter which responds to 'call', or even a lambda
|
@@ -93,76 +87,23 @@ class WCC::Contentful::Configuration
|
|
93
87
|
|
94
88
|
def initialize
|
95
89
|
@access_token = ''
|
90
|
+
@app_url = ENV['APP_URL']
|
96
91
|
@management_token = ''
|
97
92
|
@preview_token = ''
|
98
93
|
@space = ''
|
99
94
|
@default_locale = nil
|
100
95
|
@content_delivery = :direct
|
101
|
-
|
102
|
-
|
103
|
-
##
|
104
|
-
# Gets a {CDN Client}[rdoc-ref:WCC::Contentful::SimpleClient::Cdn] which provides
|
105
|
-
# methods for getting and paging raw JSON data from the Contentful CDN.
|
106
|
-
attr_reader :client
|
107
|
-
attr_reader :management_client
|
108
|
-
attr_reader :preview_client
|
109
|
-
|
110
|
-
##
|
111
|
-
# Called by WCC::Contentful.init! to configure the
|
112
|
-
# Contentful clients. This method can be called independently of `init!` if
|
113
|
-
# the application would prefer not to generate all the models.
|
114
|
-
#
|
115
|
-
# If the {contentful.rb}[https://github.com/contentful/contentful.rb] gem is
|
116
|
-
# loaded, it is extended to make use of the `http_adapter` lambda.
|
117
|
-
def configure_contentful
|
118
|
-
@client = nil
|
119
|
-
@management_client = nil
|
120
|
-
@preview_client = nil
|
121
|
-
|
122
|
-
if defined?(::ContentfulModel)
|
123
|
-
ContentfulModel.configure do |config|
|
124
|
-
config.access_token = access_token
|
125
|
-
config.management_token = management_token if management_token.present?
|
126
|
-
config.space = space
|
127
|
-
config.default_locale = default_locale || 'en-US'
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
require_relative 'client_ext' if defined?(::Contentful)
|
132
|
-
|
133
|
-
@client = WCC::Contentful::SimpleClient::Cdn.new(
|
134
|
-
access_token: access_token,
|
135
|
-
space: space,
|
136
|
-
default_locale: default_locale,
|
137
|
-
adapter: http_adapter,
|
138
|
-
environment: environment
|
139
|
-
)
|
140
|
-
|
141
|
-
if preview_token.present?
|
142
|
-
@preview_client = WCC::Contentful::SimpleClient::Preview.new(
|
143
|
-
preview_token: preview_token,
|
144
|
-
space: space,
|
145
|
-
default_locale: default_locale,
|
146
|
-
adapter: http_adapter
|
147
|
-
)
|
148
|
-
end
|
149
|
-
|
150
|
-
return unless management_token.present?
|
151
|
-
@management_client = WCC::Contentful::SimpleClient::Management.new(
|
152
|
-
management_token: management_token,
|
153
|
-
space: space,
|
154
|
-
default_locale: default_locale,
|
155
|
-
adapter: http_adapter,
|
156
|
-
environment: environment
|
157
|
-
)
|
96
|
+
@webhook_jobs = []
|
158
97
|
end
|
159
98
|
|
160
99
|
def validate!
|
161
100
|
raise ArgumentError, 'Please provide "space"' unless space.present?
|
162
101
|
raise ArgumentError, 'Please provide "access_token"' unless access_token.present?
|
163
102
|
|
164
|
-
|
165
|
-
|
166
|
-
|
103
|
+
webhook_jobs&.each do |job|
|
104
|
+
next if job.respond_to?(:call) || job.respond_to?(:perform_later)
|
105
|
+
|
106
|
+
raise ArgumentError, "The job '#{job}' must be an instance of ActiveJob::Base or respond to :call"
|
107
|
+
end
|
167
108
|
end
|
168
109
|
end
|
@@ -4,6 +4,25 @@ module WCC::Contentful
|
|
4
4
|
class Engine < ::Rails::Engine
|
5
5
|
isolate_namespace WCC::Contentful
|
6
6
|
|
7
|
+
initializer 'enable webhook' do
|
8
|
+
config = WCC::Contentful.configuration
|
9
|
+
next unless config&.management_token.present?
|
10
|
+
next unless config.app_url.present?
|
11
|
+
|
12
|
+
if Rails.env.production?
|
13
|
+
WebhookEnableJob.set(wait: 10.seconds).perform_later(
|
14
|
+
management_token: config.management_token,
|
15
|
+
app_url: config.app_url,
|
16
|
+
space: config.space,
|
17
|
+
environment: config.environment,
|
18
|
+
default_locale: config.default_locale,
|
19
|
+
adapter: config.http_adapter,
|
20
|
+
webhook_username: config.webhook_username,
|
21
|
+
webhook_password: config.webhook_password
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
7
26
|
config.generators do |g|
|
8
27
|
g.test_framework :rspec, fixture: false
|
9
28
|
end
|
@@ -1,40 +1,37 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module WCC::Contentful
|
4
|
-
class
|
5
|
-
|
6
|
-
Struct.new(:path, :error) do
|
7
|
-
def to_s
|
8
|
-
"#{path}: #{error}"
|
9
|
-
end
|
10
|
-
end
|
4
|
+
class SyncError < StandardError
|
5
|
+
end
|
11
6
|
|
12
|
-
|
7
|
+
# Raised when a constant under {WCC::Contentful::Model} does not match to a
|
8
|
+
# content type in the configured Contentful space
|
9
|
+
class ContentTypeNotFoundError < NameError
|
10
|
+
end
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
# Raised when an entry contains a circular reference and cannot be represented
|
13
|
+
# as a flat tree.
|
14
|
+
class CircularReferenceError < StandardError
|
15
|
+
attr_reader :stack
|
16
|
+
attr_reader :id
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
hash.map do |k, v|
|
24
|
-
if v.is_a?(Hash)
|
25
|
-
msgs = join_msg_keys(v)
|
26
|
-
msgs.map { |msg| Message.new(k.to_s + '.' + msg.path, msg.error) }
|
27
|
-
else
|
28
|
-
v.map { |msg| Message.new(k.to_s, msg) }
|
29
|
-
end
|
30
|
-
end
|
31
|
-
ret.flatten(1)
|
18
|
+
def initialize(stack, id)
|
19
|
+
@id = id
|
20
|
+
@stack = stack.slice(stack.index(id)..stack.length)
|
21
|
+
super('Circular reference detected!')
|
32
22
|
end
|
33
|
-
end
|
34
23
|
|
35
|
-
|
24
|
+
def message
|
25
|
+
return super unless stack
|
26
|
+
|
27
|
+
super + "\n " \
|
28
|
+
"#{stack.last} points to #{id} which is also it's ancestor\n " +
|
29
|
+
stack.join('->')
|
30
|
+
end
|
36
31
|
end
|
37
32
|
|
38
|
-
|
33
|
+
# Raised by {WCC::Contentful::ModelMethods#resolve Model#resolve} when attempting
|
34
|
+
# to resolve an entry's links and that entry cannot be found in the space.
|
35
|
+
class ResolveError < StandardError
|
39
36
|
end
|
40
37
|
end
|