storyblok 2.1.1 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +282 -0
  3. data/.rubocop_strict.yml +30 -0
  4. data/.rubocop_todo.yml +405 -0
  5. data/Gemfile +8 -3
  6. data/Gemfile.lock +92 -20
  7. data/README.md +99 -27
  8. data/coverage/.last_run.json +5 -0
  9. data/coverage/.resultset.json +547 -0
  10. data/coverage/.resultset.json.lock +0 -0
  11. data/coverage/assets/0.10.2/application.css +799 -0
  12. data/coverage/assets/0.10.2/application.js +1707 -0
  13. data/coverage/assets/0.10.2/colorbox/border.png +0 -0
  14. data/coverage/assets/0.10.2/colorbox/controls.png +0 -0
  15. data/coverage/assets/0.10.2/colorbox/loading.gif +0 -0
  16. data/coverage/assets/0.10.2/colorbox/loading_background.png +0 -0
  17. data/coverage/assets/0.10.2/favicon_green.png +0 -0
  18. data/coverage/assets/0.10.2/favicon_red.png +0 -0
  19. data/coverage/assets/0.10.2/favicon_yellow.png +0 -0
  20. data/coverage/assets/0.10.2/loading.gif +0 -0
  21. data/coverage/assets/0.10.2/magnify.png +0 -0
  22. data/coverage/assets/0.10.2/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  23. data/coverage/assets/0.10.2/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  24. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  25. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  26. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  27. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  28. data/coverage/assets/0.10.2/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  29. data/coverage/assets/0.10.2/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  30. data/coverage/assets/0.10.2/smoothness/images/ui-icons_222222_256x240.png +0 -0
  31. data/coverage/assets/0.10.2/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  32. data/coverage/assets/0.10.2/smoothness/images/ui-icons_454545_256x240.png +0 -0
  33. data/coverage/assets/0.10.2/smoothness/images/ui-icons_888888_256x240.png +0 -0
  34. data/coverage/assets/0.10.2/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  35. data/coverage/index.html +3380 -0
  36. data/examples/cache.rb +5 -6
  37. data/examples/example_queries.rb +6 -6
  38. data/examples/management_api.rb +2 -4
  39. data/examples/renderer.rb +11 -12
  40. data/examples/tree.rb +12 -12
  41. data/lib/storyblok/cache/redis.rb +3 -2
  42. data/lib/storyblok/client.rb +167 -71
  43. data/lib/storyblok/links.rb +16 -17
  44. data/lib/storyblok/version.rb +1 -1
  45. data/lib/storyblok.rb +3 -3
  46. metadata +94 -14
  47. data/.DS_Store +0 -0
  48. data/.ruby-version +0 -1
  49. data/lib/.DS_Store +0 -0
  50. data/lib/storyblok/.DS_Store +0 -0
  51. data/storyblok.gemspec +0 -23
data/examples/cache.rb CHANGED
@@ -1,16 +1,16 @@
1
1
  # bundle exec ruby examples/cache.rb
2
2
 
3
- require 'storyblok'
4
- require 'redis'
3
+ require "storyblok"
4
+ require "redis"
5
5
 
6
6
  logger = Logger.new(STDOUT)
7
7
 
8
- redis_url = 'redis://localhost:6379'
8
+ redis_url = "redis://localhost:6379"
9
9
  Storyblok::Cache.client = Redis.new(:url => redis_url)
10
10
 
11
11
  client = Storyblok::Client.new(
12
- token: 't618GfLe1YHICBioAHnMrwtt',
13
- api_url: 'localhost:3001',
12
+ token: "t618GfLe1YHICBioAHnMrwtt",
13
+ api_url: "localhost:3001",
14
14
  secure: false,
15
15
  logger: logger
16
16
  )
@@ -19,4 +19,3 @@ links = client.links
19
19
  links = client.links
20
20
  links = client.flush
21
21
  links = client.links
22
-
@@ -1,18 +1,18 @@
1
1
  # bundle exec ruby examples/example_queries.rb
2
2
 
3
- require 'storyblok'
3
+ require "storyblok"
4
4
 
5
5
  logger = Logger.new(STDOUT)
6
6
 
7
7
  client = Storyblok::Client.new(
8
- token: 't618GfLe1YHICBioAHnMrwtt',
9
- api_url: 'localhost:3001',
8
+ token: "t618GfLe1YHICBioAHnMrwtt",
9
+ api_url: "localhost:3001",
10
10
  secure: false,
11
11
  logger: logger
12
12
  )
13
13
 
14
- p client.stories(starts_with: 'en/news')
15
- p client.story('demo1')
16
- p client.datasource_entries(datasource: 'labels', per_page: 10)
14
+ p client.stories(starts_with: "en/news")
15
+ p client.story("demo1")
16
+ p client.datasource_entries(datasource: "labels", per_page: 10)
17
17
  p client.links
18
18
  p client.datasources
@@ -14,14 +14,14 @@ spaces = client.get('spaces')['data']['spaces']
14
14
  space = spaces.first
15
15
 
16
16
  p client.get("spaces/#{space['id']}")['data']['space']
17
- story_res = client.post("spaces/#{space['id']}/stories", {story: {name: 'new', slug: "new"}})['data']
17
+ story_res = client.post("spaces/#{space['id']}/stories", { story: { name: 'new', slug: "new" } })['data']
18
18
 
19
19
  10.times do |index|
20
20
  client.get("spaces/#{space['id']}/stories/#{story_res['story']['id']}")
21
21
  puts index
22
22
  end
23
23
 
24
- p client.put("spaces/#{space['id']}/stories/#{story_res['story']['id']}", {story: {name: 'new123'}})['data']
24
+ p client.put("spaces/#{space['id']}/stories/#{story_res['story']['id']}", { story: { name: 'new123' } })['data']
25
25
 
26
26
  10.times do |index|
27
27
  client.story('new')
@@ -29,5 +29,3 @@ p client.put("spaces/#{space['id']}/stories/#{story_res['story']['id']}", {story
29
29
  end
30
30
 
31
31
  p client.delete("spaces/#{space['id']}/stories/#{story_res['story']['id']}")
32
-
33
-
data/examples/renderer.rb CHANGED
@@ -1,31 +1,30 @@
1
1
  # bundle exec ruby examples/renderer.rb
2
2
 
3
- require_relative '../lib/storyblok'
4
- require 'redis'
3
+ require_relative "../lib/storyblok"
4
+ require "redis"
5
5
 
6
6
  logger = Logger.new(STDOUT)
7
7
 
8
- redis = Redis.new(url: 'redis://localhost:6379')
8
+ redis = Redis.new(url: "redis://localhost:6379")
9
9
  cache = Storyblok::Cache::Redis.new(redis: redis)
10
10
 
11
11
  client = Storyblok::Client.new(
12
- token: '6HMYdAjBoONyuS6GIf5PdAtt',
12
+ token: "6HMYdAjBoONyuS6GIf5PdAtt",
13
13
  logger: logger,
14
14
  component_resolver: ->(component, data) {
15
15
  "Placeholder for #{component}: #{data['text']}"
16
16
  },
17
- api_url: 'api-testing.storyblok.com',
17
+ api_url: "api-testing.storyblok.com",
18
18
  api_version: 2,
19
19
  cache: cache
20
20
  )
21
21
 
22
-
23
22
  res = client.flush
24
- res = client.story('authors/page', {version: 'published'})
23
+ res = client.story("authors/page", { version: "published" })
25
24
  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'})
25
+ res = client.story("authors/page", { version: "published" })
26
+ res = client.story("authors/page", { version: "published" })
27
+ res = client.story("authors/page", { version: "published" })
29
28
 
30
- puts res['data']
31
- #puts client.render(res['data']['story']['content']['intro'])
29
+ puts res["data"]
30
+ # puts client.render(res['data']['story']['content']['intro'])
data/examples/tree.rb CHANGED
@@ -1,30 +1,30 @@
1
1
  # bundle exec ruby examples/tree.rb
2
2
 
3
- require 'storyblok'
3
+ require "storyblok"
4
4
 
5
5
  logger = Logger.new(STDOUT)
6
6
 
7
7
  client = Storyblok::Client.new(
8
- token: 't618GfLe1YHICBioAHnMrwtt',
9
- api_url: 'localhost:3001',
8
+ token: "t618GfLe1YHICBioAHnMrwtt",
9
+ api_url: "localhost:3001",
10
10
  secure: false,
11
11
  logger: logger
12
12
  )
13
13
 
14
14
  tree = client.tree
15
15
 
16
- puts '<ul>'
16
+ puts "<ul>"
17
17
  tree.each do |key, item|
18
- puts '<li>' + item['item']['name']
18
+ puts "<li>" + item["item"]["name"]
19
19
 
20
- if !item['children'].empty?
21
- puts '<ul>'
22
- item['children'].each do |key, inner_item|
23
- puts '<li>' + inner_item['item']['name'] + '</li>'
20
+ if !item["children"].empty?
21
+ puts "<ul>"
22
+ item["children"].each do |key, inner_item|
23
+ puts "<li>" + inner_item["item"]["name"] + "</li>"
24
24
  end
25
- puts '</ul>'
25
+ puts "</ul>"
26
26
  end
27
27
 
28
- puts '</li>'
28
+ puts "</li>"
29
29
  end
30
- puts '</ul>'
30
+ puts "</ul>"
@@ -3,7 +3,9 @@ module Storyblok
3
3
  class Redis
4
4
  DEFAULT_CONFIGURATION = {
5
5
  ttl: 60 * 60 * 24
6
- }
6
+ }.freeze
7
+
8
+ attr_reader :redis
7
9
 
8
10
  def initialize(*args)
9
11
  options = args.last.is_a?(::Hash) ? args.pop : {}
@@ -45,7 +47,6 @@ module Storyblok
45
47
  @redis.set(key, value)
46
48
  end
47
49
  end
48
-
49
50
  end
50
51
  end
51
52
  end
@@ -11,12 +11,14 @@ module Storyblok
11
11
  class Client
12
12
  DEFAULT_CONFIGURATION = {
13
13
  secure: true,
14
- api_url: 'api.storyblok.com',
15
- api_version: 1,
14
+ api_version: 2,
16
15
  logger: false,
17
16
  log_level: Logger::INFO,
18
17
  version: 'draft',
18
+ # :nocov:
19
19
  component_resolver: ->(component, data) { '' },
20
+ # :nocov:
21
+ cache_version: Time.now.to_i,
20
22
  cache: nil
21
23
  }
22
24
 
@@ -29,6 +31,7 @@ module Storyblok
29
31
  # @option given_configuration [String] :api_url
30
32
  # @option given_configuration [Proc] :component_resolver
31
33
  # @option given_configuration [Number] :api_version
34
+ # @option given_configuration [String] :api_region
32
35
  # @option given_configuration [false, ::Logger] :logger
33
36
  # @option given_configuration [::Logger::DEBUG, ::Logger::INFO, ::Logger::WARN, ::Logger::ERROR] :log_level
34
37
  def initialize(given_configuration = {})
@@ -38,8 +41,8 @@ module Storyblok
38
41
 
39
42
  if configuration[:oauth_token]
40
43
  @rest_client = RestClient::Resource.new(base_url, :headers => {
41
- :authorization => configuration[:oauth_token]
42
- })
44
+ :authorization => configuration[:oauth_token]
45
+ })
43
46
  end
44
47
 
45
48
  @renderer = Richtext::HtmlRenderer.new
@@ -185,7 +188,13 @@ module Storyblok
185
188
  end
186
189
  end
187
190
 
188
- 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
189
198
  end
190
199
 
191
200
  def flush
@@ -213,93 +222,180 @@ module Storyblok
213
222
  end
214
223
 
215
224
  private
225
+ def parse_result(res)
226
+ { 'headers' => res.headers, 'data' => JSON.parse(res.body) }
227
+ end
216
228
 
217
- def parse_result(res)
218
- {'headers' => res.headers, 'data' => JSON.parse(res.body)}
219
- end
229
+ def run_request(endpoint, query_string)
230
+ logger.info(request: { endpoint: endpoint, query: query_string }) if logger
220
231
 
221
- def run_request(endpoint, query_string)
222
- logger.info(request: { endpoint: endpoint, query: query_string }) if logger
232
+ retries_left = 3
223
233
 
224
- retries_left = 3
234
+ begin
235
+ res = RestClient.get "#{endpoint}?#{query_string}"
236
+ rescue RestClient::TooManyRequests
237
+ if retries_left != 0
238
+ retries_left -= 1
239
+ logger.info("Too many requests. Retry nr. #{(3 - retries_left).to_s} of max. 3 times.") if logger
240
+ sleep(0.5)
241
+ retry
242
+ end
225
243
 
226
- begin
227
- res = RestClient.get "#{endpoint}?#{query_string}"
228
- rescue RestClient::TooManyRequests
229
- if retries_left != 0
230
- retries_left -= 1
231
- logger.info("Too many requests. Retry nr. #{(3 - retries_left).to_s} of max. 3 times.") if logger
232
- sleep(0.5)
233
- retry
244
+ raise
234
245
  end
235
246
 
236
- raise
247
+ body = JSON.parse(res.body)
248
+ self.cache_version = body['cv'] if body['cv']
249
+
250
+ unless cache.nil?
251
+ cache.set('storyblok:' + configuration[:token] + ':version', cache_version)
252
+ end
253
+
254
+ { 'headers' => res.headers, 'data' => body }.to_json
237
255
  end
238
256
 
239
- body = JSON.parse(res.body)
240
- self.cache_version = body['cv'] if body['cv']
257
+ # Patches a query hash with the client configurations for queries
258
+ def request_query(query)
259
+ query[:token] = configuration[:token] if query[:token].nil?
260
+ query[:version] = configuration[:version] if query[:version].nil?
241
261
 
242
- unless cache.nil?
243
- cache.set('storyblok:' + configuration[:token] + ':version', cache_version)
262
+ unless cache.nil?
263
+ query[:cv] = (cache.get('storyblok:' + configuration[:token] + ':version') or cache_version) if query[:cv].nil?
264
+ else
265
+ query[:cv] = cache_version if query[:cv].nil?
266
+ end
267
+
268
+ query
244
269
  end
245
270
 
246
- {'headers' => res.headers, 'data' => body}.to_json
247
- end
271
+ # Returns the base url for all of the client's requests
272
+ def base_url
273
+ if !configuration[:api_url]
274
+ region = configuration[:api_region] ? "-#{configuration[:api_region]}" : ""
275
+ "http#{configuration[:secure] ? 's' : ''}://api#{region}.storyblok.com/v#{configuration[:api_version]}"
276
+ else
277
+ "http#{configuration[:secure] ? 's' : ''}://#{configuration[:api_url]}/v#{configuration[:api_version]}"
278
+ end
279
+ end
248
280
 
249
- # Patches a query hash with the client configurations for queries
250
- def request_query(query)
251
- query[:token] = configuration[:token] if query[:token].nil?
252
- query[:version] = configuration[:version] if query[:version].nil?
281
+ def default_configuration
282
+ DEFAULT_CONFIGURATION.dup
283
+ end
253
284
 
254
- unless cache.nil?
255
- query[:cv] = (cache.get('storyblok:' + configuration[:token] + ':version') or cache_version) if query[:cv].nil?
256
- else
257
- query[:cv] = cache_version if query[:cv].nil?
285
+ def cache
286
+ configuration[:cache]
258
287
  end
259
288
 
260
- query
261
- end
289
+ def setup_logger
290
+ @logger = configuration[:logger]
291
+ logger.level = configuration[:log_level] if logger
292
+ end
262
293
 
263
- # Returns the base url for all of the client's requests
264
- def base_url
265
- "http#{configuration[:secure] ? 's' : ''}://#{configuration[:api_url]}/v#{configuration[:api_version]}"
266
- end
294
+ def validate_configuration!
295
+ fail ArgumentError, 'You will need to initialize a client with an :token or :oauth_token' if !configuration[:token] and !configuration[:oauth_token]
296
+ fail ArgumentError, 'The :api_version must be a positive number' unless configuration[:api_version].to_i >= 0
297
+ end
267
298
 
268
- def default_configuration
269
- DEFAULT_CONFIGURATION.dup
270
- end
299
+ def build_nested_query(value, prefix = nil)
300
+ case value
301
+ when Array
302
+ value.map { |v|
303
+ build_nested_query(v, "#{prefix}[]")
304
+ }.join("&")
305
+ when Hash
306
+ value.map { |k, v|
307
+ build_nested_query(v,
308
+ prefix ? "#{prefix}[#{URI.encode_www_form_component(k)}]" : URI.encode_www_form_component(k))
309
+ }.reject(&:empty?).join('&')
310
+ when nil
311
+ prefix
312
+ else
313
+ raise ArgumentError, "value must be a Hash" if prefix.nil?
271
314
 
272
- def cache
273
- configuration[:cache]
274
- end
315
+ "#{prefix}=#{URI.encode_www_form_component(value)}"
316
+ end
317
+ end
275
318
 
276
- def setup_logger
277
- @logger = configuration[:logger]
278
- logger.level = configuration[:log_level] if logger
279
- end
319
+ def resolve_stories(result, params)
320
+ data = result['data']
321
+ rels = data['rels']
322
+ links = data['links']
323
+ resolve_relations = params[:resolve_relations] || params["resolve_relations"]
280
324
 
281
- def validate_configuration!
282
- fail ArgumentError, 'You will need to initialize a client with an :token or :oauth_token' if !configuration[:token] and !configuration[:oauth_token]
283
- fail ArgumentError, 'The client configuration needs to contain an :api_url' if configuration[:api_url].empty?
284
- fail ArgumentError, 'The :api_version must be a positive number' unless configuration[:api_version].to_i >= 0
285
- end
325
+ if data['stories'].nil?
326
+ find_and_fill_relations(data.dig('story', 'content'), resolve_relations, rels)
327
+ find_and_fill_links(data.dig('story', 'content'), links)
328
+ else
329
+ data['stories'].each do |story|
330
+ find_and_fill_relations(story['content'], resolve_relations, rels)
331
+ find_and_fill_links(story['content'], links)
332
+ end
333
+ end
286
334
 
287
- def build_nested_query(value, prefix = nil)
288
- case value
289
- when Array
290
- value.map { |v|
291
- build_nested_query(v, "#{prefix}[]")
292
- }.join("&")
293
- when Hash
294
- value.map { |k, v|
295
- build_nested_query(v, prefix ? "#{prefix}[#{URI.encode_www_form_component(k)}]" : URI.encode_www_form_component(k))
296
- }.reject(&:empty?).join('&')
297
- when nil
298
- prefix
299
- else
300
- raise ArgumentError, "value must be a Hash" if prefix.nil?
301
- "#{prefix}=#{URI.encode_www_form_component(value)}"
335
+ result
336
+ end
337
+
338
+ def find_and_fill_links(content, links)
339
+ return if content.nil? || links.nil? || links.size.zero?
340
+
341
+ if content.is_a? Array
342
+ content.each do |item|
343
+ find_and_fill_links(item, links)
344
+ end
345
+ elsif content.is_a? Hash
346
+ content['story'] = nil
347
+ content.each do |_k, value|
348
+ if !content['fieldtype'].nil?
349
+ if content['fieldtype'] == 'multilink' && content['linktype'] == 'story'
350
+ id =
351
+ if content['id'].is_a? String
352
+ content['id']
353
+ elsif content['uuid'].is_a? String
354
+ content['uuid']
355
+ end
356
+
357
+ links.each do |link|
358
+ if link['uuid'] == id
359
+ content['story'] = link
360
+ break
361
+ end
362
+ end
363
+ end
364
+ end
365
+
366
+ find_and_fill_links(value, links)
367
+ end
368
+ content.delete('story') if content['story'].nil?
369
+ end
370
+ end
371
+
372
+ def find_and_fill_relations(content, relation_params, rels)
373
+ return if content.nil? || rels.nil? || rels.size.zero?
374
+
375
+ if content.is_a? Array
376
+ content.each do |item|
377
+ find_and_fill_relations(item, relation_params, rels)
378
+ end
379
+ elsif content.is_a? Hash
380
+ content.each do |_k, value|
381
+ if !content['component'].nil? && !content['_uid'].nil?
382
+ relation_params.split(',').each do |relation|
383
+ component, field_name = relation.split('.')
384
+
385
+ if (content['component'] == component) && !content[field_name].nil?
386
+ rels.each do |rel|
387
+ index = content[field_name].index(rel['uuid'])
388
+ if !index.nil?
389
+ content[field_name][index] = rel
390
+ end
391
+ end
392
+ end
393
+ end
394
+ end
395
+
396
+ find_and_fill_relations(value, relation_params, rels)
397
+ end
398
+ end
302
399
  end
303
- end
304
400
  end
305
401
  end
@@ -1,42 +1,41 @@
1
1
  module Storyblok
2
2
  class Links
3
3
  def initialize(response_obj)
4
- @links = response_obj['data']['links']
4
+ @links = response_obj["data"]["links"]
5
5
  end
6
6
 
7
7
  def as_tree
8
8
  tree = {}
9
9
 
10
10
  @links.each do |key, item|
11
- if tree[item['parent_id']].nil?
12
- tree[item['parent_id']] = []
11
+ if tree[item["parent_id"]].nil?
12
+ tree[item["parent_id"]] = []
13
13
  end
14
14
 
15
- tree[item['parent_id']] << item
15
+ tree[item["parent_id"]] << item
16
16
  end
17
17
 
18
18
  generate_tree(0, tree)
19
19
  end
20
20
 
21
21
  private
22
+ def generate_tree(parent_id = 0, items)
23
+ tree = {}
22
24
 
23
- def generate_tree(parent_id = 0, items)
24
- tree = {}
25
+ if !items[parent_id].nil?
26
+ result = items[parent_id]
25
27
 
26
- if !items[parent_id].nil?
27
- result = items[parent_id]
28
+ result.each do |item|
29
+ if tree[item["id"]].nil?
30
+ tree[item["id"]] = {}
31
+ end
28
32
 
29
- result.each do |item|
30
- if tree[item['id']].nil?
31
- tree[item['id']] = {}
33
+ tree[item["id"]]["item"] = item
34
+ tree[item["id"]]["children"] = generate_tree(item["id"], items)
32
35
  end
33
-
34
- tree[item['id']]['item'] = item
35
- tree[item['id']]['children'] = generate_tree(item['id'], items)
36
36
  end
37
- end
38
37
 
39
- tree
40
- end
38
+ tree
39
+ end
41
40
  end
42
41
  end
@@ -1,4 +1,4 @@
1
1
  module Storyblok
2
2
  # Gem Version
3
- VERSION = '2.1.1'
3
+ VERSION = "3.1.0"
4
4
  end
data/lib/storyblok.rb CHANGED
@@ -1,3 +1,3 @@
1
- require 'storyblok/version'
2
- require 'storyblok/cache/redis'
3
- require 'storyblok/client'
1
+ require "storyblok/version"
2
+ require "storyblok/cache/redis"
3
+ require "storyblok/client"