wcc-contentful 1.6.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b816aba232400e71ec193b4a60220a111afc356d3d6aa3a10d77f96eacea21df
4
- data.tar.gz: 95b27d0804915ef3effaf67e36e8e4ebcef39aa8001921d4e94a51c699c43a93
3
+ metadata.gz: 9c8c705f0a469c62b48b4c0635d9ef9226e4c06ae5a51b1e3798c207bd17db20
4
+ data.tar.gz: b162610307104a0c5b4fbeb94ceb16806592b5dfefe766a1d538af33a1aa3452
5
5
  SHA512:
6
- metadata.gz: ac1bcaeb7ddfe4f1f3fa2c34a542d814665e6d1428da89a4d8ae08a59686b5048d2892dc03cd9b3501a268bcf1867787a34ddeaac0b82d5791dadceef1df69e1
7
- data.tar.gz: 7b84baba5cafff0ac07e7f0e557d08389f003918f84d2da7c10a8d7e50f60d45bd6214389b2e545803ed22964c00581920fa9f614b97d6e94a2e6e75abc090bc
6
+ metadata.gz: 82a7b8759d7d28ced49cb72d790dae577bff3a6f876738efc2fbd6bcc1f5d6638a8d9f777b7046b36ef9b802b2b6e343e5e13c02fa81a7b8770a6b3b4596151b
7
+ data.tar.gz: 580df9b2f644ae00ba75b3da1e21ceacce74a0b3f0238a6fce508d9d3d0a3d7734dc5fde6b232841b4218135af49363b75c7abd974548ad769a3258ce1ce25e4
@@ -32,10 +32,18 @@ module WCC::Contentful
32
32
  next unless config&.management_token.present?
33
33
  next unless config.app_url.present?
34
34
 
35
- WebhookEnableJob.set(wait: 10.seconds).perform_later if Rails.env.production?
35
+ if defined?(WCC::Contentful::WebhookEnableJob)
36
+ WCC::Contentful::WebhookEnableJob.set(wait: 10.seconds).perform_later if Rails.env.production?
37
+ else
38
+ Rails.logger.error 'ActiveJob is not defined, webhook enable job will not run'
39
+ end
36
40
  end
37
41
  end
38
42
 
43
+ initializer 'wcc-contentful.deprecations' do |app|
44
+ app.deprecators[:wcc_contentful] = WCC::Contentful.deprecator if app.respond_to?(:deprecators)
45
+ end
46
+
39
47
  config.generators do |g|
40
48
  g.test_framework :rspec, fixture: false
41
49
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'singleton'
4
+ require 'ostruct'
4
5
 
5
6
  module WCC::Contentful::Event
6
7
  extend ActiveSupport::Concern
@@ -5,21 +5,30 @@ class WCC::Contentful::Link
5
5
 
6
6
  LINK_TYPES = {
7
7
  Asset: 'Asset',
8
- Link: 'Entry'
8
+ Link: 'Entry',
9
+ Tag: 'Tag'
9
10
  }.freeze
10
11
 
11
12
  def initialize(model, link_type = nil)
12
- @id = model.try(:id) || model
13
- @link_type = link_type
14
- @link_type ||= model.is_a?(WCC::Contentful::Model::Asset) ? :Asset : :Link
15
- @raw =
16
- {
17
- 'sys' => {
18
- 'type' => 'Link',
19
- 'linkType' => LINK_TYPES[@link_type] || link_type,
20
- 'id' => @id
13
+ if model.is_a?(Hash)
14
+ raise ArgumentError, 'Not a Link' unless model.dig('sys', 'type') == 'Link'
15
+
16
+ @raw = model
17
+ @id = model.dig('sys', 'id')
18
+ @link_type = model.dig('sys', 'linkType')
19
+ else
20
+ @id = model.try(:id) || model
21
+ @link_type = link_type
22
+ @link_type ||= model.is_a?(WCC::Contentful::Model::Asset) ? :Asset : :Link
23
+ @raw =
24
+ {
25
+ 'sys' => {
26
+ 'type' => 'Link',
27
+ 'linkType' => LINK_TYPES[@link_type] || link_type,
28
+ 'id' => @id
29
+ }
21
30
  }
22
- }
31
+ end
23
32
  end
24
33
 
25
34
  alias_method :to_h, :raw
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ WCC::Contentful::Metadata =
4
+ Struct.new(:raw) do
5
+ def tags
6
+ @tags ||=
7
+ Array(raw['tags']).map do |tag|
8
+ WCC::Contentful::Link.new(tag) if tag.is_a?(Hash)
9
+ end
10
+ end
11
+ end
@@ -41,7 +41,7 @@ module WCC::Contentful::ModelAPI
41
41
  end
42
42
 
43
43
  def store(preview = nil)
44
- ActiveSupport::Deprecation.warn('Use services.store instead')
44
+ WCC::Contentful.deprecator.warn('Use services.store instead')
45
45
 
46
46
  preview ? services.preview_store : services.store
47
47
  end
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'ostruct'
3
4
  require_relative './link'
4
5
  require_relative './sys'
6
+ require_relative './metadata'
5
7
  require_relative './rich_text'
6
8
 
7
9
  module WCC::Contentful
@@ -86,6 +88,10 @@ module WCC::Contentful
86
88
  OpenStruct.new(context).freeze
87
89
  )
88
90
 
91
+ @metadata = WCC::Contentful::Metadata.new(
92
+ raw['metadata']
93
+ )
94
+
89
95
  typedef.fields.each_value do |f|
90
96
  raw_value = raw.dig('fields', f.name)
91
97
 
@@ -119,6 +125,7 @@ module WCC::Contentful
119
125
  end
120
126
 
121
127
  attr_reader :sys
128
+ attr_reader :metadata
122
129
  attr_reader :raw
123
130
 
124
131
  delegate :id, to: :sys
@@ -65,6 +65,33 @@ class WCC::Contentful::SimpleClient::Cdn < WCC::Contentful::SimpleClient
65
65
  resp.assert_ok!
66
66
  end
67
67
 
68
+ # https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/tags/tag-collection/get-all-tags/console
69
+ def tags(query = {})
70
+ resp =
71
+ _instrument 'tags', query: query do
72
+ get('tags', query)
73
+ end
74
+ resp.assert_ok!
75
+ end
76
+
77
+ # Retrieves a single tag by ID
78
+ #
79
+ # @param id [String] The ID of the tag to retrieve
80
+ # @param query [Hash] Optional query parameters
81
+ # @return [Response] Response containing the tag
82
+ # @raise [ArgumentError] If id is nil or empty
83
+ # @example
84
+ # client.tag('sports')
85
+ def tag(id, query = {})
86
+ raise ArgumentError, 'id cannot be nil or empty' if id.nil? || id.empty?
87
+
88
+ resp =
89
+ _instrument 'tags', id: id, query: query do
90
+ get("tags/#{id}", query)
91
+ end
92
+ resp.assert_ok!
93
+ end
94
+
68
95
  # Accesses the Sync API to get a list of items that have changed since
69
96
  # the last sync. Accepts a block that receives each changed item, and returns
70
97
  # the next sync token.
@@ -109,7 +136,7 @@ class WCC::Contentful::SimpleClient::Cdn < WCC::Contentful::SimpleClient
109
136
  private
110
137
 
111
138
  def sync_old(sync_token: nil, **query)
112
- ActiveSupport::Deprecation.warn('Sync without a block is deprecated, please use new block syntax instead')
139
+ WCC::Contentful.deprecator.warn('Sync without a block is deprecated, please use new block syntax instead')
113
140
 
114
141
  sync_token =
115
142
  if sync_token
@@ -66,6 +66,34 @@ class WCC::Contentful::SimpleClient::Management < WCC::Contentful::SimpleClient
66
66
  resp.assert_ok!
67
67
  end
68
68
 
69
+ def tags(query = {})
70
+ resp =
71
+ _instrument 'tags', query: query do
72
+ get("/spaces/#{space}/environments/#{environment}/tags", query)
73
+ end
74
+ resp.assert_ok!
75
+ end
76
+
77
+ def tag(key, query = {})
78
+ resp =
79
+ _instrument 'tags', tag: key, query: query do
80
+ get("/spaces/#{space}/environments/#{environment}/tags/#{key}", query)
81
+ end
82
+ resp.assert_ok!
83
+ end
84
+
85
+ def tag_create(tag_definition)
86
+ unless tag_id = tag_definition.dig('sys', 'id')
87
+ raise ArgumentError, "Missing tag ID in #{tag_definition}"
88
+ end
89
+
90
+ resp =
91
+ _instrument 'tag_create' do
92
+ put("/spaces/#{space}/environments/#{environment}/tags/#{tag_id}", tag_definition)
93
+ end
94
+ resp.assert_ok!
95
+ end
96
+
69
97
  # {
70
98
  # "name": "My webhook",
71
99
  # "url": "https://www.example.com/test",
@@ -109,16 +137,29 @@ class WCC::Contentful::SimpleClient::Management < WCC::Contentful::SimpleClient
109
137
  resp)
110
138
  end
111
139
 
140
+ def put(path, body)
141
+ url = URI.join(@api_url, path)
142
+
143
+ resp =
144
+ _instrument 'put_http', url: url do
145
+ post_http(url, body, {}, :put)
146
+ end
147
+
148
+ Response.new(self,
149
+ { url: url, body: body },
150
+ resp)
151
+ end
152
+
112
153
  private
113
154
 
114
- def post_http(url, body, headers = {})
155
+ def post_http(url, body, headers = {}, method = :post)
115
156
  headers = {
116
157
  Authorization: "Bearer #{@access_token}",
117
158
  'Content-Type' => 'application/vnd.contentful.management.v1+json'
118
159
  }.merge(headers || {})
119
160
 
120
161
  body = body.to_json unless body.is_a? String
121
- resp = @post_adapter.post(url, body, headers)
162
+ resp = @post_adapter.public_send(method, url, body, headers)
122
163
 
123
164
  if [301, 302, 307].include?(resp.status) && !@options[:no_follow_redirects]
124
165
  resp = get_http(resp.headers['location'], nil, headers)
@@ -2,6 +2,7 @@
2
2
 
3
3
  gem 'typhoeus'
4
4
  require 'typhoeus'
5
+ require 'ostruct'
5
6
 
6
7
  class WCC::Contentful::SimpleClient::TyphoeusAdapter
7
8
  def get(url, params = {}, headers = {})
@@ -28,6 +29,18 @@ class WCC::Contentful::SimpleClient::TyphoeusAdapter
28
29
  )
29
30
  end
30
31
 
32
+ def put(url, body, headers = {}, proxy = {})
33
+ raise NotImplementedError, 'Proxying Not Yet Implemented' if proxy[:host]
34
+
35
+ Response.new(
36
+ Typhoeus.put(
37
+ url,
38
+ body: body.to_json,
39
+ headers: headers
40
+ )
41
+ )
42
+ end
43
+
31
44
  class Response < SimpleDelegator
32
45
  delegate :to_s, to: :body
33
46
 
@@ -26,7 +26,7 @@ module WCC::Contentful
26
26
  class SimpleClient
27
27
  include WCC::Contentful::Instrumentation
28
28
 
29
- attr_reader :api_url, :space
29
+ attr_reader :api_url, :space, :environment
30
30
 
31
31
  # Creates a new SimpleClient with the given configuration.
32
32
  #
@@ -54,9 +54,10 @@ module WCC::Contentful
54
54
  # https://www.contentful.com/developers/docs/references/content-preview-api/#/introduction/api-rate-limits
55
55
  @rate_limit_wait_timeout = @options[:rate_limit_wait_timeout] || 1.5
56
56
 
57
- return unless options[:environment].present?
57
+ @environment = options[:environment]
58
+ return unless @environment.present?
58
59
 
59
- @api_url = URI.join(@api_url, 'environments/', "#{options[:environment]}/")
60
+ @api_url = URI.join(@api_url, 'environments/', "#{@environment}/")
60
61
  end
61
62
 
62
63
  # performs an HTTP GET request to the specified path within the configured
@@ -224,6 +224,94 @@ RSpec.shared_examples 'basic store' do
224
224
  found2 = subject.find('1qLdW7i7g4Ycq6i4Cckg44')
225
225
  expect(found2.dig('fields', 'slug', 'en-US')).to eq('redirect-with-slug-and-url')
226
226
  end
227
+
228
+ it 'stores metadata including tags', focus: true do
229
+ entry_with_tags = JSON.parse <<~JSON
230
+ {
231
+ "metadata": {
232
+ "tags": [
233
+ {
234
+ "sys": {
235
+ "type": "Link",
236
+ "linkType": "Tag",
237
+ "id": "ministry_careers-in-motion"
238
+ }
239
+ }
240
+ ],
241
+ "concepts": []
242
+ },
243
+ "sys": {
244
+ "space": {
245
+ "sys": {
246
+ "type": "Link",
247
+ "linkType": "Space",
248
+ "id": "hw5pse7y1ojx"
249
+ }
250
+ },
251
+ "id": "1h5ce0SYZq8cELhESiJFkA",
252
+ "type": "Entry",
253
+ "createdAt": "2020-02-06T20:25:19.188Z",
254
+ "updatedAt": "2024-11-21T19:02:37.381Z",
255
+ "environment": {
256
+ "sys": {
257
+ "id": "dev",
258
+ "type": "Link",
259
+ "linkType": "Environment"
260
+ }
261
+ },
262
+ "publishedVersion": 73,
263
+ "revision": 7,
264
+ "contentType": {
265
+ "sys": {
266
+ "type": "Link",
267
+ "linkType": "ContentType",
268
+ "id": "page"
269
+ }
270
+ }
271
+ },
272
+ "fields": {
273
+ "title": {
274
+ "en-US": "Finances and Career Care"
275
+ },
276
+ "slug": {
277
+ "en-US": "/ministries/financialcareers"
278
+ },
279
+ "sections": {
280
+ "en-US": [
281
+ {
282
+ "sys": {
283
+ "type": "Link",
284
+ "linkType": "Entry",
285
+ "id": "4agnOGg0LQZrCbF4OeMEbj"
286
+ }
287
+ },
288
+ {
289
+ "sys": {
290
+ "type": "Link",
291
+ "linkType": "Entry",
292
+ "id": "614GfdpLaD5gjc0U3sITXY"
293
+ }
294
+ },
295
+ {
296
+ "sys": {
297
+ "type": "Link",
298
+ "linkType": "Entry",
299
+ "id": "xM5NWKiZSRUoUxXvoiYW4"
300
+ }
301
+ }
302
+ ]
303
+ }
304
+ }
305
+ }
306
+ JSON
307
+
308
+ # act
309
+ subject.set('1h5ce0SYZq8cELhESiJFkA', entry_with_tags)
310
+ found = subject.find('1h5ce0SYZq8cELhESiJFkA')
311
+
312
+ # assert
313
+ expect(found.dig('metadata', 'tags', 0, 'sys', 'id')).to eq('ministry_careers-in-motion')
314
+ end
227
315
  end
228
316
 
229
317
  describe '#delete' do
@@ -160,6 +160,119 @@ RSpec.shared_examples 'supports include param' do |feature_set|
160
160
  expect(link.dig('sys', 'type')).to eq('Entry')
161
161
  expect(link.dig('sys', 'id')).to eq('deep0')
162
162
  end
163
+
164
+ it 'preserves tags' do
165
+ entry_with_tags = JSON.parse <<~JSON
166
+ {
167
+ "metadata": {
168
+ "tags": [
169
+ {
170
+ "sys": {
171
+ "type": "Link",
172
+ "linkType": "Tag",
173
+ "id": "ministry_careers-in-motion"
174
+ }
175
+ }
176
+ ],
177
+ "concepts": []
178
+ },
179
+ "sys": {
180
+ "space": {
181
+ "sys": {
182
+ "type": "Link",
183
+ "linkType": "Space",
184
+ "id": "hw5pse7y1ojx"
185
+ }
186
+ },
187
+ "id": "1h5ce0SYZq8cELhESiJFkA",
188
+ "type": "Entry",
189
+ "createdAt": "2020-02-06T20:25:19.188Z",
190
+ "updatedAt": "2024-11-21T19:02:37.381Z",
191
+ "environment": {
192
+ "sys": {
193
+ "id": "dev",
194
+ "type": "Link",
195
+ "linkType": "Environment"
196
+ }
197
+ },
198
+ "publishedVersion": 73,
199
+ "revision": 7,
200
+ "contentType": {
201
+ "sys": {
202
+ "type": "Link",
203
+ "linkType": "ContentType",
204
+ "id": "page"
205
+ }
206
+ }
207
+ },
208
+ "fields": {
209
+ "title": {
210
+ "en-US": "Finances and Career Care"
211
+ },
212
+ "slug": {
213
+ "en-US": "/ministries/financialcareers"
214
+ },
215
+ "sections": {
216
+ "en-US": [
217
+ {
218
+ "sys": {
219
+ "type": "Link",
220
+ "linkType": "Entry",
221
+ "id": "4agnOGg0LQZrCbF4OeMEbj"
222
+ }
223
+ }
224
+ ]
225
+ }
226
+ }
227
+ }
228
+ JSON
229
+ linked_entry = JSON.parse(<<~JSON)
230
+ {
231
+ "metadata": {
232
+ "tags": [
233
+ {
234
+ "sys": {
235
+ "type": "Link",
236
+ "linkType": "Tag",
237
+ "id": "ministry_something-else"
238
+ }
239
+ }
240
+ ],
241
+ "concepts": []
242
+ },
243
+ "sys": {
244
+ "id": "4agnOGg0LQZrCbF4OeMEbj",
245
+ "type": "Entry",
246
+ "contentType": {
247
+ "sys": {
248
+ "type": "Link",
249
+ "linkType": "ContentType",
250
+ "id": "page"
251
+ }
252
+ }
253
+ },
254
+ "fields": {
255
+ "name": {
256
+ "en-US": "Linked Entry"
257
+ }
258
+ }
259
+ }
260
+ JSON
261
+
262
+ subject.set('1h5ce0SYZq8cELhESiJFkA', entry_with_tags)
263
+ subject.set('4agnOGg0LQZrCbF4OeMEbj', linked_entry)
264
+
265
+ # act
266
+ found = subject.find_by(content_type: 'page', filter: { slug: '/ministries/financialcareers' }, options: {
267
+ include: 1
268
+ })
269
+
270
+ # assert
271
+ expect(found.dig('metadata', 'tags', 0, 'sys', 'id')).to eq('ministry_careers-in-motion')
272
+ linked = found.dig('fields', 'sections', 'en-US', 0)
273
+ expect(linked.dig('fields', 'name', 'en-US')).to eq('Linked Entry')
274
+ expect(linked.dig('metadata', 'tags', 0, 'sys', 'id')).to eq('ministry_something-else')
275
+ end
163
276
  end
164
277
 
165
278
  describe '#find_all' do
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'ostruct'
4
+
3
5
  require_relative './attributes'
4
6
 
5
7
  module WCC::Contentful::Test::Double
@@ -2,6 +2,6 @@
2
2
 
3
3
  module WCC
4
4
  module Contentful
5
- VERSION = '1.6.1'
5
+ VERSION = '1.7.0'
6
6
  end
7
7
  end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WCC::Contentful
4
+ if defined?(ActiveJob)
5
+ class WebhookEnableJob < ActiveJob::Base
6
+ self.queue_adapter = :async
7
+ queue_as :default
8
+
9
+ def perform(args = {})
10
+ args = default_configuration.merge!(args)
11
+
12
+ client = WCC::Contentful::SimpleClient::Management.new(
13
+ **args
14
+ )
15
+ enable_webhook(client, **args.slice(:receive_url, :webhook_username, :webhook_password))
16
+ end
17
+
18
+ def enable_webhook(client, receive_url:, webhook_username: nil, webhook_password: nil)
19
+ webhook = client.webhook_definitions.items.find { |w| w['url'] == receive_url }
20
+ logger.debug "existing webhook: #{webhook.inspect}" if webhook
21
+ return if webhook
22
+
23
+ body = {
24
+ 'name' => 'WCC::Contentful webhook',
25
+ 'url' => receive_url,
26
+ 'topics' => [
27
+ '*.publish',
28
+ '*.unpublish'
29
+ ],
30
+ 'filters' => webhook_filters
31
+ }
32
+ body['httpBasicUsername'] = webhook_username if webhook_username.present?
33
+ body['httpBasicPassword'] = webhook_password if webhook_password.present?
34
+
35
+ begin
36
+ resp = client.post_webhook_definition(body)
37
+ logger.info "Created webhook: #{resp.raw.dig('sys', 'id')}"
38
+ rescue WCC::Contentful::SimpleClient::ApiError => e
39
+ logger.error "#{e.response.code}: #{e.response.raw}" if e.response
40
+ raise
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def default_configuration
47
+ return {} unless config = WCC::Contentful&.configuration
48
+
49
+ {
50
+ management_token: config.management_token,
51
+ space: config.space,
52
+ environment: config.environment,
53
+ connection: config.connection,
54
+ webhook_username: config.webhook_username,
55
+ webhook_password: config.webhook_password,
56
+
57
+ receive_url: URI.join(config.app_url, 'webhook/receive').to_s
58
+ }
59
+ end
60
+
61
+ def webhook_filters
62
+ filters = []
63
+
64
+ if (environment_id = WCC::Contentful.configuration&.environment).present?
65
+ filters << {
66
+ 'equals' => [
67
+ { 'doc' => 'sys.environment.sys.id' },
68
+ environment_id
69
+ ]
70
+ }
71
+ end
72
+ filters
73
+ end
74
+ end
75
+ end
76
+ end
@@ -24,6 +24,7 @@ require 'wcc/contentful/rich_text'
24
24
  require 'wcc/contentful/rich_text_renderer'
25
25
  require 'wcc/contentful/rich_text_renderer_factory'
26
26
  require 'wcc/contentful/sync_engine'
27
+ require 'wcc/contentful/webhook_enable_job'
27
28
  require 'wcc/contentful/events'
28
29
  require 'wcc/contentful/middleware'
29
30
 
@@ -39,7 +40,7 @@ module WCC::Contentful
39
40
  attr_reader :configuration
40
41
 
41
42
  def types
42
- ActiveSupport::Deprecation.warn('Use WCC::Contentful::Model.schema instead')
43
+ WCC::Contentful.deprecator.warn('Use WCC::Contentful::Model.schema instead')
43
44
  WCC::Contentful::Model.schema
44
45
  end
45
46
 
@@ -49,9 +50,20 @@ module WCC::Contentful
49
50
  end
50
51
 
51
52
  def logger
52
- ActiveSupport::Deprecation.warn('Use WCC::Contentful::Services.instance.logger instead')
53
+ WCC::Contentful.deprecator.warn('Use WCC::Contentful::Services.instance.logger instead')
53
54
  WCC::Contentful::Services.instance.logger
54
55
  end
56
+
57
+ def deprecator
58
+ @deprecator ||=
59
+ begin
60
+ next_major_version = WCC::Contentful::VERSION.split('.').first.next
61
+ ActiveSupport::Deprecation.new(
62
+ "#{next_major_version}.0",
63
+ 'wcc-contentful'
64
+ )
65
+ end
66
+ end
55
67
  end
56
68
 
57
69
  # Configures the WCC::Contentful gem to talk to a Contentful space.
@@ -30,7 +30,6 @@ Gem::Specification.new do |spec|
30
30
 
31
31
  spec.require_paths = ['lib']
32
32
 
33
- spec.add_development_dependency 'byebug', '~> 11.0.1'
34
33
  spec.add_development_dependency 'coveralls'
35
34
  spec.add_development_dependency 'dotenv', '~> 2.2'
36
35
  spec.add_development_dependency 'erb_lint', '~> 0.0.26'
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wcc-contentful
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.1
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Watermark Dev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-27 00:00:00.000000000 Z
11
+ date: 2024-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: byebug
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: 11.0.1
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: 11.0.1
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: coveralls
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -419,7 +405,6 @@ files:
419
405
  - Rakefile
420
406
  - app/controllers/wcc/contentful/application_controller.rb
421
407
  - app/controllers/wcc/contentful/webhook_controller.rb
422
- - app/jobs/wcc/contentful/webhook_enable_job.rb
423
408
  - config/initializers/mime_types.rb
424
409
  - config/routes.rb
425
410
  - lib/tasks/download_schema.rake
@@ -440,6 +425,7 @@ files:
440
425
  - lib/wcc/contentful/instrumentation.rb
441
426
  - lib/wcc/contentful/link.rb
442
427
  - lib/wcc/contentful/link_visitor.rb
428
+ - lib/wcc/contentful/metadata.rb
443
429
  - lib/wcc/contentful/middleware.rb
444
430
  - lib/wcc/contentful/middleware/store.rb
445
431
  - lib/wcc/contentful/middleware/store/caching_middleware.rb
@@ -494,12 +480,13 @@ files:
494
480
  - lib/wcc/contentful/test/double.rb
495
481
  - lib/wcc/contentful/test/factory.rb
496
482
  - lib/wcc/contentful/version.rb
483
+ - lib/wcc/contentful/webhook_enable_job.rb
497
484
  - wcc-contentful.gemspec
498
485
  homepage: https://github.com/watermarkchurch/wcc-contentful/wcc-contentful
499
486
  licenses:
500
487
  - MIT
501
488
  metadata:
502
- documentation_uri: https://watermarkchurch.github.io/wcc-contentful/1.6/wcc-contentful
489
+ documentation_uri: https://watermarkchurch.github.io/wcc-contentful/1.7/wcc-contentful
503
490
  rubygems_mfa_required: 'true'
504
491
  post_install_message:
505
492
  rdoc_options: []
@@ -516,7 +503,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
516
503
  - !ruby/object:Gem::Version
517
504
  version: '0'
518
505
  requirements: []
519
- rubygems_version: 3.4.10
506
+ rubygems_version: 3.5.16
520
507
  signing_key:
521
508
  specification_version: 4
522
509
  summary: '[![Gem Version](https://badge.fury.io/rb/wcc-contentful.svg)](https://rubygems.org/gems/wcc-contentful)
@@ -1,76 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_job'
4
-
5
- module WCC::Contentful
6
- class WebhookEnableJob < ActiveJob::Base
7
- self.queue_adapter = :async
8
- queue_as :default
9
-
10
- def perform(args = {})
11
- args = default_configuration.merge!(args)
12
-
13
- client = WCC::Contentful::SimpleClient::Management.new(
14
- **args
15
- )
16
- enable_webhook(client, **args.slice(:receive_url, :webhook_username, :webhook_password))
17
- end
18
-
19
- def enable_webhook(client, receive_url:, webhook_username: nil, webhook_password: nil)
20
- webhook = client.webhook_definitions.items.find { |w| w['url'] == receive_url }
21
- logger.debug "existing webhook: #{webhook.inspect}" if webhook
22
- return if webhook
23
-
24
- body = {
25
- 'name' => 'WCC::Contentful webhook',
26
- 'url' => receive_url,
27
- 'topics' => [
28
- '*.publish',
29
- '*.unpublish'
30
- ],
31
- 'filters' => webhook_filters
32
- }
33
- body['httpBasicUsername'] = webhook_username if webhook_username.present?
34
- body['httpBasicPassword'] = webhook_password if webhook_password.present?
35
-
36
- begin
37
- resp = client.post_webhook_definition(body)
38
- logger.info "Created webhook: #{resp.raw.dig('sys', 'id')}"
39
- rescue WCC::Contentful::SimpleClient::ApiError => e
40
- logger.error "#{e.response.code}: #{e.response.raw}" if e.response
41
- raise
42
- end
43
- end
44
-
45
- private
46
-
47
- def default_configuration
48
- return {} unless config = WCC::Contentful&.configuration
49
-
50
- {
51
- management_token: config.management_token,
52
- space: config.space,
53
- environment: config.environment,
54
- connection: config.connection,
55
- webhook_username: config.webhook_username,
56
- webhook_password: config.webhook_password,
57
-
58
- receive_url: URI.join(config.app_url, 'webhook/receive').to_s
59
- }
60
- end
61
-
62
- def webhook_filters
63
- filters = []
64
-
65
- if (environment_id = WCC::Contentful.configuration&.environment).present?
66
- filters << {
67
- 'equals' => [
68
- { 'doc' => 'sys.environment.sys.id' },
69
- environment_id
70
- ]
71
- }
72
- end
73
- filters
74
- end
75
- end
76
- end