wcc-contentful 0.2.2 → 0.3.0.pre.rc
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This module is extended by all models and defines singleton
|
4
|
+
# methods that are not dynamically generated.
|
5
|
+
# @api Model
|
6
|
+
module WCC::Contentful::ModelSingletonMethods
|
7
|
+
def store(preview = false)
|
8
|
+
if preview
|
9
|
+
if WCC::Contentful::Model.preview_store.nil?
|
10
|
+
raise ArgumentError,
|
11
|
+
'You must include a contentful preview token in your WCC::Contentful.configure block'
|
12
|
+
end
|
13
|
+
WCC::Contentful::Model.preview_store
|
14
|
+
else
|
15
|
+
WCC::Contentful::Model.store
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Finds an instance of this content type.
|
20
|
+
#
|
21
|
+
# @return [nil, WCC::Contentful::Model] An instance of the appropriate model class
|
22
|
+
# for this content type, or nil if the ID does not exist in the space.
|
23
|
+
# @example
|
24
|
+
# WCC::Contentful::Model::Page.find(id)
|
25
|
+
def find(id, options: nil)
|
26
|
+
options ||= {}
|
27
|
+
raw = store(options[:preview])
|
28
|
+
.find(id, { hint: type }.merge!(options.except(:preview)))
|
29
|
+
new(raw, options) if raw.present?
|
30
|
+
end
|
31
|
+
|
32
|
+
# Finds all instances of this content type, optionally limiting to those matching
|
33
|
+
# a given filter query.
|
34
|
+
#
|
35
|
+
# @return [Enumerator::Lazy<WCC::Contentful::Model>, <WCC::Contentful::Model>]
|
36
|
+
# A set of instantiated model objects matching the given query.
|
37
|
+
# @example
|
38
|
+
# WCC::Contentful::Model::Page.find_all('sys.created_at' => { lte: Date.today })
|
39
|
+
def find_all(filter = nil)
|
40
|
+
filter = filter&.dup
|
41
|
+
options = filter&.delete(:options) || {}
|
42
|
+
|
43
|
+
if filter.present?
|
44
|
+
filter.transform_keys! { |k| k.to_s.camelize(:lower) }
|
45
|
+
bad_fields = filter.keys.reject { |k| self::FIELDS.include?(k) }
|
46
|
+
raise ArgumentError, "These fields do not exist: #{bad_fields}" unless bad_fields.empty?
|
47
|
+
end
|
48
|
+
|
49
|
+
query = store(options[:preview])
|
50
|
+
.find_all(content_type: content_type, options: options.except(:preview))
|
51
|
+
query = query.apply(filter) if filter.present?
|
52
|
+
query.map { |r| new(r, options) }
|
53
|
+
end
|
54
|
+
|
55
|
+
# Finds the first instance of this content type matching the given query.
|
56
|
+
#
|
57
|
+
# @return [nil, WCC::Contentful::Model] A set of instantiated model objects matching
|
58
|
+
# the given query.
|
59
|
+
# @example
|
60
|
+
# WCC::Contentful::Model::Page.find_by(slug: '/some-slug')
|
61
|
+
def find_by(filter = nil)
|
62
|
+
filter = filter&.dup
|
63
|
+
options = filter&.delete(:options) || {}
|
64
|
+
|
65
|
+
if filter.present?
|
66
|
+
filter.transform_keys! { |k| k.to_s.camelize(:lower) }
|
67
|
+
bad_fields = filter.keys.reject { |k| self::FIELDS.include?(k) }
|
68
|
+
raise ArgumentError, "These fields do not exist: #{bad_fields}" unless bad_fields.empty?
|
69
|
+
end
|
70
|
+
|
71
|
+
result = store(options[:preview])
|
72
|
+
.find_by(content_type: content_type, filter: filter, options: options.except(:preview))
|
73
|
+
|
74
|
+
new(result, options) if result
|
75
|
+
end
|
76
|
+
|
77
|
+
def inherited(subclass)
|
78
|
+
# only register if it's not already registered
|
79
|
+
return if WCC::Contentful::Model.registered?(content_type)
|
80
|
+
|
81
|
+
WCC::Contentful::Model.register_for_content_type(content_type, klass: subclass)
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'singleton'
|
4
|
+
|
5
|
+
module WCC::Contentful
|
6
|
+
class Services
|
7
|
+
include Singleton
|
8
|
+
|
9
|
+
# Gets the data-store which executes the queries run against the dynamic
|
10
|
+
# models in the WCC::Contentful::Model namespace.
|
11
|
+
# This is one of the following based on the configured content_delivery method:
|
12
|
+
#
|
13
|
+
# [:direct] an instance of {WCC::Contentful::Store::CDNAdapter} with a
|
14
|
+
# {WCC::Contentful::SimpleClient::Cdn CDN Client} to access the CDN.
|
15
|
+
#
|
16
|
+
# [:lazy_sync] an instance of {WCC::Contentful::Store::LazyCacheStore}
|
17
|
+
# with the configured ActiveSupport::Cache implementation and a
|
18
|
+
# {WCC::Contentful::SimpleClient::Cdn CDN Client} for when data
|
19
|
+
# cannot be found in the cache.
|
20
|
+
#
|
21
|
+
# [:eager_sync] an instance of the configured Store type, defined by
|
22
|
+
# {WCC::Contentful::Configuration#sync_store}
|
23
|
+
#
|
24
|
+
# @api Store
|
25
|
+
def store
|
26
|
+
@store ||=
|
27
|
+
ensure_configured do |config|
|
28
|
+
WCC::Contentful::Store::Factory.new(
|
29
|
+
config,
|
30
|
+
self,
|
31
|
+
config.content_delivery,
|
32
|
+
config.content_delivery_params
|
33
|
+
).build_sync_store
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# An instance of {WCC::Contentful::Store::CDNAdapter} which connects to the
|
38
|
+
# Contentful Preview API to return preview content.
|
39
|
+
#
|
40
|
+
# @api Store
|
41
|
+
def preview_store
|
42
|
+
@preview_store ||=
|
43
|
+
ensure_configured do |config|
|
44
|
+
WCC::Contentful::Store::Factory.new(
|
45
|
+
config,
|
46
|
+
self,
|
47
|
+
:direct,
|
48
|
+
[{ preview: true }]
|
49
|
+
).build_sync_store
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Gets a {WCC::Contentful::SimpleClient::Cdn CDN Client} which provides
|
54
|
+
# methods for getting and paging raw JSON data from the Contentful CDN.
|
55
|
+
#
|
56
|
+
# @api Client
|
57
|
+
def client
|
58
|
+
@client ||=
|
59
|
+
ensure_configured do |config|
|
60
|
+
WCC::Contentful::SimpleClient::Cdn.new(
|
61
|
+
access_token: config.access_token,
|
62
|
+
space: config.space,
|
63
|
+
default_locale: config.default_locale,
|
64
|
+
adapter: config.http_adapter,
|
65
|
+
environment: config.environment
|
66
|
+
)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Gets a {WCC::Contentful::SimpleClient::Cdn CDN Client} which provides
|
71
|
+
# methods for getting and paging raw JSON data from the Contentful Preview API.
|
72
|
+
#
|
73
|
+
# @api Client
|
74
|
+
def preview_client
|
75
|
+
@preview_client ||=
|
76
|
+
ensure_configured do |config|
|
77
|
+
if config.preview_token.present?
|
78
|
+
WCC::Contentful::SimpleClient::Preview.new(
|
79
|
+
preview_token: config.preview_token,
|
80
|
+
space: config.space,
|
81
|
+
default_locale: config.default_locale,
|
82
|
+
adapter: config.http_adapter,
|
83
|
+
environment: config.environment
|
84
|
+
)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Gets a {WCC::Contentful::SimpleClient::Management Management Client} which provides
|
90
|
+
# methods for updating data via the Contentful Management API
|
91
|
+
#
|
92
|
+
# @api Client
|
93
|
+
def management_client
|
94
|
+
@management_client ||=
|
95
|
+
ensure_configured do |config|
|
96
|
+
if config.management_token.present?
|
97
|
+
WCC::Contentful::SimpleClient::Management.new(
|
98
|
+
management_token: config.management_token,
|
99
|
+
space: config.space,
|
100
|
+
default_locale: config.default_locale,
|
101
|
+
adapter: config.http_adapter,
|
102
|
+
environment: config.environment
|
103
|
+
)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def ensure_configured
|
111
|
+
if WCC::Contentful.configuration.nil?
|
112
|
+
raise StandardError, 'WCC::Contentful has not yet been configured!'
|
113
|
+
end
|
114
|
+
|
115
|
+
yield WCC::Contentful.configuration
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Include this module to define accessors for every method defined on the
|
120
|
+
# {Services} singleton.
|
121
|
+
#
|
122
|
+
# @example
|
123
|
+
# class MyJob < ApplicationJob
|
124
|
+
# include WCC::Contentful::ServiceAccessors
|
125
|
+
#
|
126
|
+
# def perform
|
127
|
+
# Page.find(...)
|
128
|
+
#
|
129
|
+
# store.find(...)
|
130
|
+
#
|
131
|
+
# client.entries(...)
|
132
|
+
# end
|
133
|
+
# end
|
134
|
+
# @see Services
|
135
|
+
module ServiceAccessors
|
136
|
+
SERVICES = (WCC::Contentful::Services.instance_methods -
|
137
|
+
Object.instance_methods -
|
138
|
+
Singleton.instance_methods)
|
139
|
+
|
140
|
+
SERVICES.each do |m|
|
141
|
+
define_method m do
|
142
|
+
Services.instance.public_send(m)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -1,33 +1,59 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'simple_client/response'
|
4
|
+
require_relative 'simple_client/management'
|
4
5
|
|
5
6
|
module WCC::Contentful
|
6
|
-
##
|
7
7
|
# The SimpleClient accesses the Contentful CDN to get JSON responses,
|
8
|
-
# returning the raw JSON data as a parsed hash.
|
8
|
+
# returning the raw JSON data as a parsed hash. This is the bottom layer of
|
9
|
+
# the WCC::Contentful gem.
|
10
|
+
#
|
11
|
+
# Note: Do not create this directly, instead create one of
|
12
|
+
# WCC::Contentful::SimpleClient::Cdn, WCC::Contentful::SimpleClient::Preview,
|
13
|
+
# WCC::Contentful::SimpleClient::Management
|
14
|
+
#
|
9
15
|
# It can be configured to access any API url and exposes only a single method,
|
10
16
|
# `get`. This method returns a WCC::Contentful::SimpleClient::Response
|
11
17
|
# that handles paging automatically.
|
12
18
|
#
|
13
19
|
# The SimpleClient by default uses 'http' to perform the gets, but any HTTP
|
14
20
|
# client can be injected by passing a proc as the `adapter:` option.
|
21
|
+
#
|
22
|
+
# @api Client
|
15
23
|
class SimpleClient
|
24
|
+
attr_reader :api_url
|
25
|
+
attr_reader :space
|
26
|
+
|
27
|
+
# Creates a new SimpleClient with the given configuration.
|
28
|
+
#
|
29
|
+
# @param [String] api_url the base URL of the Contentful API to connect to
|
30
|
+
# @param [String] space The Space ID to access
|
31
|
+
# @param [String] access_token A Contentful Access Token to be sent in the Authorization header
|
32
|
+
# @param [Hash] options The remaining optional parameters, defined below
|
33
|
+
# @option options [Symbol, Object] adapter The Adapter to use to make requests.
|
34
|
+
# Auto-discovered based on what gems are installed if this is not provided.
|
35
|
+
# @option options [String] default_locale The locale query param to set by default.
|
36
|
+
# @option options [String] environment The contentful environment to access. Defaults to 'master'.
|
37
|
+
# @option options [Boolean] no_follow_redirects If true, do not follow 300 level redirects.
|
16
38
|
def initialize(api_url:, space:, access_token:, **options)
|
17
39
|
@api_url = URI.join(api_url, '/spaces/', space + '/')
|
18
40
|
@space = space
|
19
41
|
@access_token = access_token
|
20
42
|
|
21
|
-
@
|
43
|
+
@adapter = SimpleClient.load_adapter(options[:adapter])
|
22
44
|
|
23
45
|
@options = options
|
24
46
|
@query_defaults = {}
|
25
47
|
@query_defaults[:locale] = @options[:default_locale] if @options[:default_locale]
|
26
48
|
|
27
|
-
return unless
|
28
|
-
|
49
|
+
return unless options[:environment].present?
|
50
|
+
|
51
|
+
@api_url = URI.join(@api_url, 'environments/', options[:environment] + '/')
|
29
52
|
end
|
30
53
|
|
54
|
+
# performs an HTTP GET request to the specified path within the configured
|
55
|
+
# space and environment. Query parameters are merged with the defaults and
|
56
|
+
# appended to the request.
|
31
57
|
def get(path, query = {})
|
32
58
|
url = URI.join(@api_url, path)
|
33
59
|
|
@@ -79,7 +105,7 @@ module WCC::Contentful
|
|
79
105
|
q = @query_defaults.dup
|
80
106
|
q = q.merge(query) if query
|
81
107
|
|
82
|
-
resp = @
|
108
|
+
resp = @adapter.call(url, q, headers, proxy)
|
83
109
|
|
84
110
|
if [301, 302, 307].include?(resp.code) && !@options[:no_follow_redirects]
|
85
111
|
resp = get_http(resp.headers['location'], nil, headers, proxy)
|
@@ -87,11 +113,12 @@ module WCC::Contentful
|
|
87
113
|
resp
|
88
114
|
end
|
89
115
|
|
90
|
-
##
|
91
116
|
# The CDN SimpleClient accesses 'https://cdn.contentful.com' to get raw
|
92
117
|
# JSON responses. It exposes methods to query entries, assets, and content_types.
|
93
118
|
# The responses are instances of WCC::Contentful::SimpleClient::Response
|
94
119
|
# which handles paging automatically.
|
120
|
+
#
|
121
|
+
# @api Client
|
95
122
|
class Cdn < SimpleClient
|
96
123
|
def initialize(space:, access_token:, **options)
|
97
124
|
super(
|
@@ -106,42 +133,36 @@ module WCC::Contentful
|
|
106
133
|
'cdn'
|
107
134
|
end
|
108
135
|
|
109
|
-
##
|
110
136
|
# Gets an entry by ID
|
111
137
|
def entry(key, query = {})
|
112
138
|
resp = get("entries/#{key}", query)
|
113
139
|
resp.assert_ok!
|
114
140
|
end
|
115
141
|
|
116
|
-
##
|
117
142
|
# Queries entries with optional query parameters
|
118
143
|
def entries(query = {})
|
119
144
|
resp = get('entries', query)
|
120
145
|
resp.assert_ok!
|
121
146
|
end
|
122
147
|
|
123
|
-
##
|
124
148
|
# Gets an asset by ID
|
125
149
|
def asset(key, query = {})
|
126
150
|
resp = get("assets/#{key}", query)
|
127
151
|
resp.assert_ok!
|
128
152
|
end
|
129
153
|
|
130
|
-
##
|
131
154
|
# Queries assets with optional query parameters
|
132
155
|
def assets(query = {})
|
133
156
|
resp = get('assets', query)
|
134
157
|
resp.assert_ok!
|
135
158
|
end
|
136
159
|
|
137
|
-
##
|
138
160
|
# Queries content types with optional query parameters
|
139
161
|
def content_types(query = {})
|
140
162
|
resp = get('content_types', query)
|
141
163
|
resp.assert_ok!
|
142
164
|
end
|
143
165
|
|
144
|
-
##
|
145
166
|
# Accesses the Sync API to get a list of items that have changed since
|
146
167
|
# the last sync.
|
147
168
|
#
|
@@ -161,26 +182,7 @@ module WCC::Contentful
|
|
161
182
|
end
|
162
183
|
end
|
163
184
|
|
164
|
-
|
165
|
-
def initialize(space:, management_token:, **options)
|
166
|
-
super(
|
167
|
-
api_url: options[:api_url] || 'https://api.contentful.com',
|
168
|
-
space: space,
|
169
|
-
access_token: management_token,
|
170
|
-
**options
|
171
|
-
)
|
172
|
-
end
|
173
|
-
|
174
|
-
def client_type
|
175
|
-
'management'
|
176
|
-
end
|
177
|
-
|
178
|
-
def content_types(**query)
|
179
|
-
resp = get('content_types', query)
|
180
|
-
resp.assert_ok!
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
185
|
+
# @api Client
|
184
186
|
class Preview < Cdn
|
185
187
|
def initialize(space:, preview_token:, **options)
|
186
188
|
super(
|
@@ -12,4 +12,13 @@ class HttpAdapter
|
|
12
12
|
HTTP[headers].get(url, params: query)
|
13
13
|
end
|
14
14
|
end
|
15
|
+
|
16
|
+
def post(url, body, headers = {}, proxy = {})
|
17
|
+
if proxy[:host]
|
18
|
+
HTTP[headers].via(proxy[:host], proxy[:port], proxy[:username], proxy[:password])
|
19
|
+
.post(url, json: body)
|
20
|
+
else
|
21
|
+
HTTP[headers].post(url, json: body)
|
22
|
+
end
|
23
|
+
end
|
15
24
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api Client
|
4
|
+
class WCC::Contentful::SimpleClient::Management < WCC::Contentful::SimpleClient
|
5
|
+
def initialize(space:, management_token:, **options)
|
6
|
+
super(
|
7
|
+
api_url: options[:api_url] || 'https://api.contentful.com',
|
8
|
+
space: space,
|
9
|
+
access_token: management_token,
|
10
|
+
**options
|
11
|
+
)
|
12
|
+
|
13
|
+
@post_adapter = @adapter if @adapter.respond_to?(:post)
|
14
|
+
@post_adapter ||= self.class.load_adapter(nil)
|
15
|
+
end
|
16
|
+
|
17
|
+
def client_type
|
18
|
+
'management'
|
19
|
+
end
|
20
|
+
|
21
|
+
def content_types(**query)
|
22
|
+
resp = get('content_types', query)
|
23
|
+
resp.assert_ok!
|
24
|
+
end
|
25
|
+
|
26
|
+
def webhook_definitions(**query)
|
27
|
+
resp = get("/spaces/#{space}/webhook_definitions", query)
|
28
|
+
resp.assert_ok!
|
29
|
+
end
|
30
|
+
|
31
|
+
# {
|
32
|
+
# "name": "My webhook",
|
33
|
+
# "url": "https://www.example.com/test",
|
34
|
+
# "topics": [
|
35
|
+
# "Entry.create",
|
36
|
+
# "ContentType.create",
|
37
|
+
# "*.publish",
|
38
|
+
# "Asset.*"
|
39
|
+
# ],
|
40
|
+
# "httpBasicUsername": "yolo",
|
41
|
+
# "httpBasicPassword": "yolo",
|
42
|
+
# "headers": [
|
43
|
+
# {
|
44
|
+
# "key": "header1",
|
45
|
+
# "value": "value1"
|
46
|
+
# },
|
47
|
+
# {
|
48
|
+
# "key": "header2",
|
49
|
+
# "value": "value2"
|
50
|
+
# }
|
51
|
+
# ]
|
52
|
+
# }
|
53
|
+
def post_webhook_definition(webhook)
|
54
|
+
resp = post("/spaces/#{space}/webhook_definitions", webhook)
|
55
|
+
resp.assert_ok!
|
56
|
+
end
|
57
|
+
|
58
|
+
def post(path, body)
|
59
|
+
url = URI.join(@api_url, path)
|
60
|
+
|
61
|
+
Response.new(self,
|
62
|
+
{ url: url, body: body },
|
63
|
+
post_http(url, body))
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def post_http(url, body, headers = {}, proxy = {})
|
69
|
+
headers = {
|
70
|
+
Authorization: "Bearer #{@access_token}",
|
71
|
+
'Content-Type' => 'application/vnd.contentful.management.v1+json'
|
72
|
+
}.merge(headers || {})
|
73
|
+
|
74
|
+
resp = @post_adapter.post(url, body, headers, proxy)
|
75
|
+
|
76
|
+
if [301, 302, 307].include?(resp.code) && !@options[:no_follow_redirects]
|
77
|
+
resp = get_http(resp.headers['location'], nil, headers, proxy)
|
78
|
+
end
|
79
|
+
resp
|
80
|
+
end
|
81
|
+
end
|