storyblok 2.0.8 → 3.0.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/Gemfile.lock +2 -2
- data/README.md +36 -4
- data/examples/renderer.rb +16 -8
- data/lib/storyblok/cache/redis.rb +3 -1
- data/lib/storyblok/client.rb +117 -16
- data/lib/storyblok/request.rb +4 -3
- data/lib/storyblok/version.rb +1 -1
- metadata +58 -3
- data/storyblok.gemspec +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0a390c17a7c90bad28b7a799a7f151486d55d38977a98257cf67a1cd539e9dd
|
4
|
+
data.tar.gz: 54f9aaad47ad4d435cd40292fc969e9250c5f934c278475880f83a077e49b7cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 179c3cc2405a6370ab2cc924fa925df5df0a2737b18cd76ac6c6183e3c980889dd1782a4b3cb6f3f0e963124e138639864b6ed04fd293286c647fcf03a092424
|
7
|
+
data.tar.gz: aff00d8502c0816aac6078e68d4060db5a8041249c695f5e55c2c2ea8825ebf63efd788fd408acb9f9408ad57ce9f375eb098a5cb05253f8c820b1b3cd8c25aa
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
storyblok (2.0.
|
4
|
+
storyblok (2.0.8)
|
5
5
|
rest-client (>= 1.8.0, < 3)
|
6
6
|
storyblok-richtext-renderer (>= 0.0.4, < 1)
|
7
7
|
|
@@ -16,7 +16,7 @@ GEM
|
|
16
16
|
domain_name (~> 0.5)
|
17
17
|
mime-types (3.3)
|
18
18
|
mime-types-data (~> 3.2015)
|
19
|
-
mime-types-data (3.2019.
|
19
|
+
mime-types-data (3.2019.1009)
|
20
20
|
netrc (0.11.0)
|
21
21
|
redis (4.1.0)
|
22
22
|
rest-client (2.1.0)
|
data/README.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
|
+
[](https://codeclimate.com/github/storyblok/storyblok-ruby/test_coverage)
|
2
|
+

|
3
|
+
[](https://rubygems.org/gems/storyblok)
|
4
|
+
[](https://www.rubydoc.info/gems/storyblok)
|
5
|
+
[](https://codeclimate.com/github/storyblok/storyblok-ruby/maintainability)
|
6
|
+
|
1
7
|
# About
|
2
|
-
This is the Storyblok ruby client for easy access of the management and content delivery api.
|
8
|
+
This is the official [Storyblok](https://www.storyblok.com/) ruby client for easy access of the management and content delivery api.
|
3
9
|
|
4
10
|
## Install
|
5
11
|
|
@@ -120,7 +126,7 @@ client.flush
|
|
120
126
|
client = Storyblok::Client.new(oauth_token: 'YOUR_OAUTH_TOKEN')
|
121
127
|
|
122
128
|
# Get your spaces
|
123
|
-
client.get('spaces')
|
129
|
+
client.get('spaces/')
|
124
130
|
```
|
125
131
|
|
126
132
|
### Create a story
|
@@ -158,12 +164,12 @@ Storyblok's richtext field also let's you insert content blocks. To render these
|
|
158
164
|
```ruby
|
159
165
|
# Option 1: Define the resolver when initializing
|
160
166
|
client = Storyblok::Client.new(
|
161
|
-
component_resolver: ->(component, data)
|
167
|
+
component_resolver: ->(component, data) {
|
162
168
|
case component
|
163
169
|
when 'button'
|
164
170
|
"<button>#{data['text']}</button>"
|
165
171
|
when 'your_custom_component'
|
166
|
-
"<div class=
|
172
|
+
"<div class='welcome'>#{data['welcome_text']}</div>"
|
167
173
|
end
|
168
174
|
}
|
169
175
|
)
|
@@ -183,6 +189,32 @@ gem build storyblok.gemspec
|
|
183
189
|
gem push storyblok-2.0.X.gem
|
184
190
|
~~~
|
185
191
|
|
192
|
+
### Running Tests
|
193
|
+
We use [RSpec](http://rspec.info/) for testing.
|
194
|
+
|
195
|
+
#### To run the whole test suite you will need export the environment variables, ATTENTION when running the test suit with the variable `REDIS_URL` exported, the test suite will remove the keys with this pattern `storyblok:*` from the redis database defined by `REDIS_URL`
|
196
|
+
|
197
|
+
```bash
|
198
|
+
export REDIS_URL="redis://localhost:6379"
|
199
|
+
```
|
200
|
+
|
201
|
+
Optionally you can generate the test report coverage by setting the environment variable
|
202
|
+
|
203
|
+
```bash
|
204
|
+
export COVERAGE=true
|
205
|
+
```
|
206
|
+
|
207
|
+
To run the whole test suite use the following command:
|
208
|
+
|
209
|
+
```bash
|
210
|
+
rspec
|
211
|
+
```
|
212
|
+
|
213
|
+
To run tests without redis cache tests (for when you don't have redis, or to avoid the test suite to remove the keys with this pattern `storyblok:*` ):
|
214
|
+
|
215
|
+
```bash
|
216
|
+
rspec --tag ~redis_cache:true
|
217
|
+
```
|
186
218
|
|
187
219
|
### License
|
188
220
|
|
data/examples/renderer.rb
CHANGED
@@ -1,23 +1,31 @@
|
|
1
1
|
# bundle exec ruby examples/renderer.rb
|
2
2
|
|
3
3
|
require_relative '../lib/storyblok'
|
4
|
+
require 'redis'
|
4
5
|
|
5
6
|
logger = Logger.new(STDOUT)
|
6
7
|
|
8
|
+
redis = Redis.new(url: 'redis://localhost:6379')
|
9
|
+
cache = Storyblok::Cache::Redis.new(redis: redis)
|
10
|
+
|
7
11
|
client = Storyblok::Client.new(
|
8
12
|
token: '6HMYdAjBoONyuS6GIf5PdAtt',
|
9
13
|
logger: logger,
|
10
14
|
component_resolver: ->(component, data) {
|
11
15
|
"Placeholder for #{component}: #{data['text']}"
|
12
|
-
}
|
16
|
+
},
|
17
|
+
api_url: 'api-testing.storyblok.com',
|
18
|
+
api_version: 2,
|
19
|
+
cache: cache
|
13
20
|
)
|
14
21
|
|
15
|
-
puts client.render({'type' => 'doc', 'content' => [
|
16
|
-
{'type' => 'paragraph', 'content' => [{'text' => 'Good', 'type' => 'text'}]},
|
17
|
-
{'type' => 'blok', 'attrs' => {'body' => [{'component' => 'button', 'text' => 'Click me'}]}}
|
18
|
-
]})
|
19
22
|
|
20
|
-
res = client.
|
23
|
+
res = client.flush
|
24
|
+
res = client.story('authors/page', {version: 'published'})
|
25
|
+
puts client.cache_version
|
26
|
+
res = client.story('authors/page', {version: 'published'})
|
27
|
+
res = client.story('authors/page', {version: 'published'})
|
28
|
+
res = client.story('authors/page', {version: 'published'})
|
21
29
|
|
22
|
-
puts res['data']
|
23
|
-
puts client.render(res['data']['story']['content']['intro'])
|
30
|
+
puts res['data']
|
31
|
+
#puts client.render(res['data']['story']['content']['intro'])
|
data/lib/storyblok/client.rb
CHANGED
@@ -12,16 +12,19 @@ module Storyblok
|
|
12
12
|
DEFAULT_CONFIGURATION = {
|
13
13
|
secure: true,
|
14
14
|
api_url: 'api.storyblok.com',
|
15
|
-
api_version:
|
15
|
+
api_version: 2,
|
16
16
|
logger: false,
|
17
17
|
log_level: Logger::INFO,
|
18
18
|
version: 'draft',
|
19
|
+
# :nocov:
|
19
20
|
component_resolver: ->(component, data) { '' },
|
21
|
+
# :nocov:
|
20
22
|
cache_version: Time.now.to_i,
|
21
23
|
cache: nil
|
22
24
|
}
|
23
25
|
|
24
26
|
attr_reader :configuration, :logger
|
27
|
+
attr_accessor :cache_version
|
25
28
|
|
26
29
|
# @param [Hash] given_configuration
|
27
30
|
# @option given_configuration [String] :token Required if oauth_token is not set
|
@@ -33,6 +36,7 @@ module Storyblok
|
|
33
36
|
# @option given_configuration [::Logger::DEBUG, ::Logger::INFO, ::Logger::WARN, ::Logger::ERROR] :log_level
|
34
37
|
def initialize(given_configuration = {})
|
35
38
|
@configuration = default_configuration.merge(given_configuration)
|
39
|
+
@cache_version = '0'
|
36
40
|
validate_configuration!
|
37
41
|
|
38
42
|
if configuration[:oauth_token]
|
@@ -62,7 +66,7 @@ module Storyblok
|
|
62
66
|
#
|
63
67
|
# @return [Hash]
|
64
68
|
def space(query = {})
|
65
|
-
Request.new(self, '/cdn/spaces/me', query).get
|
69
|
+
Request.new(self, '/cdn/spaces/me', query, nil, true).get
|
66
70
|
end
|
67
71
|
|
68
72
|
# Gets a collection of stories
|
@@ -169,32 +173,34 @@ module Storyblok
|
|
169
173
|
parse_result(res)
|
170
174
|
end
|
171
175
|
|
172
|
-
def cached_get(request)
|
176
|
+
def cached_get(request, bypass_cache = false)
|
173
177
|
endpoint = base_url + request.url
|
178
|
+
query = request_query(request.query)
|
179
|
+
query_string = build_nested_query(query)
|
174
180
|
|
175
|
-
if cache.nil?
|
176
|
-
query = request_query(request.query)
|
177
|
-
query_string = build_nested_query(query)
|
181
|
+
if cache.nil? || bypass_cache || query[:version] == 'draft'
|
178
182
|
result = run_request(endpoint, query_string)
|
179
183
|
else
|
180
|
-
|
181
|
-
|
182
|
-
query = query = request_query({ cache_version: version }.merge(request.query))
|
183
|
-
query_string = build_nested_query(query)
|
184
|
-
|
185
|
-
cache_key = 'storyblok:' + configuration[:token] + ':v:' + version + ':' + request.url + ':' + Base64.encode64(query_string)
|
184
|
+
cache_key = 'storyblok:' + configuration[:token] + ':v:' + query[:cv] + ':' + request.url + ':' + Base64.encode64(query_string)
|
186
185
|
|
187
186
|
result = cache.cache(cache_key) do
|
188
187
|
run_request(endpoint, query_string)
|
189
188
|
end
|
190
189
|
end
|
191
190
|
|
192
|
-
JSON.parse(result)
|
191
|
+
result = JSON.parse(result)
|
192
|
+
|
193
|
+
if !result.dig('data', 'story').nil? || !result.dig('data', 'stories').nil?
|
194
|
+
result = resolve_stories(result, query)
|
195
|
+
end
|
196
|
+
|
197
|
+
result
|
193
198
|
end
|
194
199
|
|
200
|
+
|
195
201
|
def flush
|
196
202
|
unless cache.nil?
|
197
|
-
cache.set('storyblok:' + configuration[:token] + ':version',
|
203
|
+
cache.set('storyblok:' + configuration[:token] + ':version', space['data']['space']['version'])
|
198
204
|
end
|
199
205
|
end
|
200
206
|
|
@@ -240,14 +246,27 @@ module Storyblok
|
|
240
246
|
raise
|
241
247
|
end
|
242
248
|
|
243
|
-
|
249
|
+
body = JSON.parse(res.body)
|
250
|
+
self.cache_version = body['cv'] if body['cv']
|
251
|
+
|
252
|
+
unless cache.nil?
|
253
|
+
cache.set('storyblok:' + configuration[:token] + ':version', cache_version)
|
254
|
+
end
|
255
|
+
|
256
|
+
{'headers' => res.headers, 'data' => body}.to_json
|
244
257
|
end
|
245
258
|
|
246
259
|
# Patches a query hash with the client configurations for queries
|
247
260
|
def request_query(query)
|
248
261
|
query[:token] = configuration[:token] if query[:token].nil?
|
249
262
|
query[:version] = configuration[:version] if query[:version].nil?
|
250
|
-
|
263
|
+
|
264
|
+
unless cache.nil?
|
265
|
+
query[:cv] = (cache.get('storyblok:' + configuration[:token] + ':version') or cache_version) if query[:cv].nil?
|
266
|
+
else
|
267
|
+
query[:cv] = cache_version if query[:cv].nil?
|
268
|
+
end
|
269
|
+
|
251
270
|
query
|
252
271
|
end
|
253
272
|
|
@@ -292,5 +311,87 @@ module Storyblok
|
|
292
311
|
"#{prefix}=#{URI.encode_www_form_component(value)}"
|
293
312
|
end
|
294
313
|
end
|
314
|
+
|
315
|
+
def resolve_stories(result, params)
|
316
|
+
data = result['data']
|
317
|
+
rels = data['rels']
|
318
|
+
links = data['links']
|
319
|
+
resolve_relations = params[:resolve_relations] || params["resolve_relations"]
|
320
|
+
|
321
|
+
if data['stories'].nil?
|
322
|
+
find_and_fill_relations(data.dig('story', 'content'), resolve_relations, rels)
|
323
|
+
find_and_fill_links(data.dig('story', 'content'), links)
|
324
|
+
else
|
325
|
+
data['stories'].each do |story|
|
326
|
+
find_and_fill_relations(story['content'], resolve_relations, rels)
|
327
|
+
find_and_fill_links(story['content'], links)
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
result
|
332
|
+
end
|
333
|
+
|
334
|
+
def find_and_fill_links(content, links)
|
335
|
+
return if content.nil? || links.nil? || links.size.zero?
|
336
|
+
|
337
|
+
if content.is_a? Array
|
338
|
+
content.each do |item|
|
339
|
+
find_and_fill_links(item, links)
|
340
|
+
end
|
341
|
+
elsif content.is_a? Hash
|
342
|
+
content['story'] = nil
|
343
|
+
content.each do |_k, value|
|
344
|
+
if !content['fieldtype'].nil?
|
345
|
+
if content['fieldtype'] == 'multilink' && content['linktype'] == 'story'
|
346
|
+
id =
|
347
|
+
if content['id'].is_a? String
|
348
|
+
content['id']
|
349
|
+
elsif content['uuid'].is_a? String
|
350
|
+
content['uuid']
|
351
|
+
end
|
352
|
+
|
353
|
+
links.each do |link|
|
354
|
+
if link['uuid'] == id
|
355
|
+
content['story'] = link
|
356
|
+
break
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
find_and_fill_links(value, links)
|
363
|
+
end
|
364
|
+
content.delete('story') if content['story'].nil?
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
def find_and_fill_relations(content, relation_params, rels)
|
369
|
+
return if content.nil? || rels.nil? || rels.size.zero?
|
370
|
+
|
371
|
+
if content.is_a? Array
|
372
|
+
content.each do |item|
|
373
|
+
find_and_fill_relations(item, relation_params, rels)
|
374
|
+
end
|
375
|
+
elsif content.is_a? Hash
|
376
|
+
content.each do |_k, value|
|
377
|
+
if !content['component'].nil? && !content['_uid'].nil?
|
378
|
+
relation_params.split(',').each do |relation|
|
379
|
+
component, field_name = relation.split('.')
|
380
|
+
|
381
|
+
if (content['component'] == component) && !content[field_name].nil?
|
382
|
+
rels.each do |rel|
|
383
|
+
index = content[field_name].index(rel['uuid'])
|
384
|
+
if !index.nil?
|
385
|
+
content[field_name][index] = rel
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
find_and_fill_relations(value, relation_params, rels)
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
295
396
|
end
|
296
397
|
end
|
data/lib/storyblok/request.rb
CHANGED
@@ -5,14 +5,15 @@ module Storyblok
|
|
5
5
|
class Request
|
6
6
|
attr_reader :client, :type, :query, :id, :endpoint
|
7
7
|
|
8
|
-
def initialize(client, endpoint, query = {}, id = nil)
|
8
|
+
def initialize(client, endpoint, query = {}, id = nil, bypass_cache = false)
|
9
9
|
@client = client
|
10
10
|
@endpoint = endpoint
|
11
11
|
@query = query
|
12
|
+
@bypass_cache = bypass_cache
|
12
13
|
|
13
14
|
if id
|
14
15
|
@type = :single
|
15
|
-
@id =
|
16
|
+
@id = id
|
16
17
|
else
|
17
18
|
@type = :multi
|
18
19
|
@id = nil
|
@@ -26,7 +27,7 @@ module Storyblok
|
|
26
27
|
|
27
28
|
# Delegates the actual HTTP work to the client
|
28
29
|
def get
|
29
|
-
client.cached_get(self)
|
30
|
+
client.cached_get(self, @bypass_cache)
|
30
31
|
end
|
31
32
|
|
32
33
|
# Returns a new Request object with the same data
|
data/lib/storyblok/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: storyblok
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Storyblok (Alexander Feiglstorfer)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -64,6 +64,20 @@ dependencies:
|
|
64
64
|
- - "~>"
|
65
65
|
- !ruby/object:Gem::Version
|
66
66
|
version: '1.5'
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: hashdiff
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - "~>"
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: 1.0.1
|
74
|
+
type: :development
|
75
|
+
prerelease: false
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - "~>"
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 1.0.1
|
67
81
|
- !ruby/object:Gem::Dependency
|
68
82
|
name: rspec
|
69
83
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,6 +92,48 @@ dependencies:
|
|
78
92
|
- - "~>"
|
79
93
|
- !ruby/object:Gem::Version
|
80
94
|
version: '3'
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: webmock
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - '='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 3.14.0
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - '='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: 3.14.0
|
109
|
+
- !ruby/object:Gem::Dependency
|
110
|
+
name: vcr
|
111
|
+
requirement: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - '='
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: 6.0.0
|
116
|
+
type: :development
|
117
|
+
prerelease: false
|
118
|
+
version_requirements: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - '='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 6.0.0
|
123
|
+
- !ruby/object:Gem::Dependency
|
124
|
+
name: simplecov
|
125
|
+
requirement: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - "<"
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: 0.18.0
|
130
|
+
type: :development
|
131
|
+
prerelease: false
|
132
|
+
version_requirements: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - "<"
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: 0.18.0
|
81
137
|
description: Ruby client for the https://www.storyblok.com management and content
|
82
138
|
delivery API
|
83
139
|
email: it@storyblok.com
|
@@ -105,7 +161,6 @@ files:
|
|
105
161
|
- lib/storyblok/links.rb
|
106
162
|
- lib/storyblok/request.rb
|
107
163
|
- lib/storyblok/version.rb
|
108
|
-
- storyblok.gemspec
|
109
164
|
homepage: https://github.com/storyblok/storyblok-ruby
|
110
165
|
licenses:
|
111
166
|
- MIT
|
data/storyblok.gemspec
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
require File.expand_path('../lib/storyblok/version', __FILE__)
|
2
|
-
|
3
|
-
Gem::Specification.new do |gem|
|
4
|
-
gem.name = 'storyblok'
|
5
|
-
gem.version = Storyblok::VERSION
|
6
|
-
gem.summary = 'storyblok'
|
7
|
-
gem.description = 'Ruby client for the https://www.storyblok.com management and content delivery API'
|
8
|
-
gem.license = 'MIT'
|
9
|
-
gem.authors = ['Storyblok (Alexander Feiglstorfer)']
|
10
|
-
gem.email = 'it@storyblok.com'
|
11
|
-
gem.homepage = 'https://github.com/storyblok/storyblok-ruby'
|
12
|
-
|
13
|
-
gem.files = Dir['{**/}{.*,*}'].select { |path| File.file?(path) && !path.start_with?('pkg') && !path.end_with?('.gem') }
|
14
|
-
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
15
|
-
gem.test_files = gem.files.grep(%r{^spec/})
|
16
|
-
gem.require_paths = ['lib']
|
17
|
-
|
18
|
-
gem.add_dependency 'rest-client', '>= 1.8.0', '< 3'
|
19
|
-
gem.add_dependency 'storyblok-richtext-renderer', '>= 0.0.4', '< 1'
|
20
|
-
|
21
|
-
gem.add_development_dependency 'bundler', '~> 1.5'
|
22
|
-
gem.add_development_dependency 'rspec', '~> 3'
|
23
|
-
end
|