kontent-ai-delivery 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +21 -0
  3. data/README.md +617 -0
  4. data/bin/console +14 -0
  5. data/bin/setup +8 -0
  6. data/lib/delivery/builders/image_transformation_builder.rb +272 -0
  7. data/lib/delivery/builders/url_builder.rb +123 -0
  8. data/lib/delivery/client/delivery_client.rb +184 -0
  9. data/lib/delivery/client/delivery_query.rb +308 -0
  10. data/lib/delivery/client/request_manager.rb +127 -0
  11. data/lib/delivery/models/content_item.rb +153 -0
  12. data/lib/delivery/models/content_type.rb +41 -0
  13. data/lib/delivery/models/language.rb +29 -0
  14. data/lib/delivery/models/pagination.rb +22 -0
  15. data/lib/delivery/models/taxonomy_group.rb +39 -0
  16. data/lib/delivery/query_parameters/filters.rb +201 -0
  17. data/lib/delivery/query_parameters/parameter_base.rb +56 -0
  18. data/lib/delivery/query_parameters/query_string.rb +78 -0
  19. data/lib/delivery/resolvers/content_link_resolver.rb +102 -0
  20. data/lib/delivery/resolvers/inline_content_item_resolver.rb +75 -0
  21. data/lib/delivery/resolvers/linked_item_resolver.rb +43 -0
  22. data/lib/delivery/responses/delivery_element_response.rb +34 -0
  23. data/lib/delivery/responses/delivery_item_listing_response.rb +54 -0
  24. data/lib/delivery/responses/delivery_item_response.rb +40 -0
  25. data/lib/delivery/responses/delivery_items_feed_response.rb +58 -0
  26. data/lib/delivery/responses/delivery_language_listing_response.rb +44 -0
  27. data/lib/delivery/responses/delivery_taxonomy_listing_response.rb +47 -0
  28. data/lib/delivery/responses/delivery_taxonomy_response.rb +33 -0
  29. data/lib/delivery/responses/delivery_type_listing_response.rb +46 -0
  30. data/lib/delivery/responses/delivery_type_response.rb +32 -0
  31. data/lib/delivery/responses/response_base.rb +39 -0
  32. data/lib/delivery/tests/401.json +6 -0
  33. data/lib/delivery/tests/429.json +5 -0
  34. data/lib/delivery/tests/fake_responder.rb +99 -0
  35. data/lib/delivery/tests/filtering/items_with_count.json +5385 -0
  36. data/lib/delivery/tests/filtering/pagination.json +762 -0
  37. data/lib/delivery/tests/generic/items/about_us.json +277 -0
  38. data/lib/delivery/tests/generic/items/aeropress_filters.json +156 -0
  39. data/lib/delivery/tests/generic/items/coffee_processing_techniques.json +566 -0
  40. data/lib/delivery/tests/generic/items/empty_rich_text.json +24 -0
  41. data/lib/delivery/tests/generic/items/rich_text_complex_tables.json +81 -0
  42. data/lib/delivery/tests/generic/items/where_does_coffee_come_from_.json +599 -0
  43. data/lib/delivery/tests/generic/items.json +5384 -0
  44. data/lib/delivery/tests/generic/languages.json +24 -0
  45. data/lib/delivery/tests/generic/taxonomies/manufacturer.json +30 -0
  46. data/lib/delivery/tests/generic/taxonomies.json +204 -0
  47. data/lib/delivery/tests/generic/types/brewer/elements/product_status.json +6 -0
  48. data/lib/delivery/tests/generic/types/brewer.json +89 -0
  49. data/lib/delivery/tests/generic/types.json +836 -0
  50. data/lib/delivery/tests/items_feed/articles_feed_1.json +39 -0
  51. data/lib/delivery/tests/items_feed/articles_feed_2.json +78 -0
  52. data/lib/delivery/tests/items_feed/articles_feed_3.json +104 -0
  53. data/lib/kontent-ai-delivery.rb +22 -0
  54. metadata +221 -0
@@ -0,0 +1,39 @@
1
+ module Kontent
2
+ module Ai
3
+ module Delivery
4
+ class TaxonomyGroup
5
+ # Parses the 'terms' JSON node as a dynamic OpenStruct object.
6
+ #
7
+ # * *Returns*:
8
+ # - +OpenStruct+ The terms of the taxonomy group as a dynamic object
9
+ def terms
10
+ @terms unless @terms.nil?
11
+ @terms = JSON.parse(
12
+ JSON.generate(@source['terms']),
13
+ object_class: OpenStruct
14
+ )
15
+ end
16
+
17
+ # Parses the 'system' JSON node as a dynamic OpenStruct object.
18
+ #
19
+ # * *Returns*:
20
+ # - +OpenStruct+ The system properties of the taxonomy group
21
+ def system
22
+ @system unless @system.nil?
23
+ @system = JSON.parse(
24
+ JSON.generate(@source['system']),
25
+ object_class: OpenStruct
26
+ )
27
+ end
28
+
29
+ # Constructor.
30
+ #
31
+ # * *Args*:
32
+ # - *json* (+JSON+) A JSON node representing a taxonomy group
33
+ def initialize(source)
34
+ @source = source
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,201 @@
1
+ require 'delivery/query_parameters/parameter_base'
2
+
3
+ module Kontent
4
+ module Ai
5
+ module Delivery
6
+ module QueryParameters
7
+ # Provides the base class for filter implementations.
8
+ # See https://kontent.ai/learn/reference/delivery-api/#tag/Filtering-content
9
+ class Filter < ParameterBase
10
+ # Constructor.
11
+ #
12
+ # * *Args*:
13
+ # - *key* (+string+) The field to filter upon
14
+ # - *operator* (+string+) The Kontent.ai filter being applied to the field, in brackets
15
+ # - *values* (+Object+) One or more values which will appear as the value of the query string parameter
16
+ # - *eq_sign* (+boolean+) If false, the equals sign is not generated in the parameter
17
+ def initialize(key, operator, values, eq_sign = true)
18
+ super(key, operator, values, eq_sign)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ # Extend String class to allow semantic typing of filters
27
+ class String
28
+ # Represents a filter that matches a content item if the specified content
29
+ # element or system attribute has a value that contains all the specified
30
+ # values. This filter is applicable to array values only, such as sitemap
31
+ # location or value of Linked Items, Taxonomy and Multiple choice content elements.
32
+ #
33
+ # * *Args*:
34
+ # - +Object+ One or more objects representing the values that must appear in the field
35
+ #
36
+ # * *Returns*:
37
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
38
+ def all(*args)
39
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[all]', *args)
40
+ end
41
+
42
+ # Represents a filter that matches a content item if the specified content
43
+ # element or system attribute has a value that contains any the specified
44
+ # values. This filter is applicable to array values only, such as sitemap
45
+ # location or value of Linked Items, Taxonomy and Multiple choice content elements.
46
+ #
47
+ # * *Args*:
48
+ # - +Object+ One or more objects representing the values that may appear in the field
49
+ #
50
+ # * *Returns*:
51
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
52
+ def any(*args)
53
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[any]', *args)
54
+ end
55
+
56
+ # Represents a filter that matches a content item if the specified content element
57
+ # or system attribute has a value that contains the specified value.
58
+ # This filter is applicable to array values only, such as sitemap location or value
59
+ # of Linked Items, Taxonomy and Multiple choice content elements.
60
+ #
61
+ # * *Args*:
62
+ # - +Object+ An object representing the value that must appear in the field
63
+ #
64
+ # * *Returns*:
65
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
66
+ def contains(*args)
67
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[contains]', *args)
68
+ end
69
+
70
+ # Represents a filter that matches a content item if the specified
71
+ # content element or system attribute has the specified value.
72
+ #
73
+ # * *Args*:
74
+ # - +Object+ An object representing the value that must equal the value in the field
75
+ #
76
+ # * *Returns*:
77
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
78
+ def eq(*args)
79
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '', *args)
80
+ end
81
+
82
+ # Represents a filter that matches a content item if the specified
83
+ # content element or system attribute does not have the specified value.
84
+ #
85
+ # * *Args*:
86
+ # - +Object+ An object representing the value that cannot exist in the element
87
+ #
88
+ # * *Returns*:
89
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
90
+ def not_eq(*args)
91
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[neq]', *args)
92
+ end
93
+
94
+ # Represents a filter that matches a content item if the specified
95
+ # content element or system attribute does not have any value.
96
+ #
97
+ # * *Returns*:
98
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
99
+ def empty
100
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[empty]', nil, false)
101
+ end
102
+
103
+ # Represents a filter that matches a content item if the specified
104
+ # content element or system attribute has any value.
105
+ #
106
+ # * *Returns*:
107
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
108
+ def not_empty
109
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[nempty]', nil, false)
110
+ end
111
+
112
+ # Represents a filter that matches a content item if the specified
113
+ # content element or system attribute does not have the specified value.
114
+ #
115
+ # * *Args*:
116
+ # - +Object+ An object representing the value that cannot exist in the element
117
+ #
118
+ # * *Returns*:
119
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
120
+ def not_in(*args)
121
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[nin]', *args)
122
+ end
123
+
124
+ # Represents a filter that matches a content item if the specified content
125
+ # element or system attribute has a value that is greater than the
126
+ # specified value.
127
+ #
128
+ # * *Args*:
129
+ # - +Object+ An object representing the lowest possible value of the field, non-inclusive
130
+ #
131
+ # * *Returns*:
132
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
133
+ def gt(*args)
134
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[gt]', *args)
135
+ end
136
+
137
+ # Represents a filter that matches a content item if the specified content
138
+ # element or system attribute has a value that is greater than or equal to
139
+ # the specified value.
140
+ #
141
+ # * *Args*:
142
+ # - +Object+ An object representing the lowest possible value of the field
143
+ #
144
+ # * *Returns*:
145
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
146
+ def gt_or_eq(*args)
147
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[gte]', *args)
148
+ end
149
+
150
+ # Represents a filter that matches a content item if the specified
151
+ # content element or system attribute has a value that matches a
152
+ # value in the specified list.
153
+ #
154
+ # * *Args*:
155
+ # - +Object+ One or more objects representing the required values of the field
156
+ #
157
+ # * *Returns*:
158
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
159
+ def in(*args)
160
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[in]', *args)
161
+ end
162
+
163
+ # Represents a filter that matches a content item if the specified content
164
+ # element or system attribute has a value that is less than the
165
+ # specified value.
166
+ #
167
+ # * *Args*:
168
+ # - +Object+ An object representing the highest possible value of the field, non-inclusive
169
+ #
170
+ # * *Returns*:
171
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
172
+ def lt(*args)
173
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[lt]', *args)
174
+ end
175
+
176
+ # Represents a filter that matches a content item if the specified content
177
+ # element or system attribute has a value that is less than or equal to
178
+ # the specified value.
179
+ #
180
+ # * *Args*:
181
+ # - +Object+ An object representing the highest possible value of the field
182
+ #
183
+ # * *Returns*:
184
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
185
+ def lt_or_eq(*args)
186
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[lte]', *args)
187
+ end
188
+
189
+ # Represents a filter that matches a content item if the specified
190
+ # content element or system attribute has a value that falls within
191
+ # the specified range of values (both inclusive).
192
+ #
193
+ # * *Args*:
194
+ # - +Object+ An object representing the lowest and highest possible values of the field
195
+ #
196
+ # * *Returns*:
197
+ # - Kontent::Ai::Delivery::QueryParameters::Filter
198
+ def range(*args)
199
+ Kontent::Ai::Delivery::QueryParameters::Filter.new(self, '[range]', *args)
200
+ end
201
+ end
@@ -0,0 +1,56 @@
1
+ require 'cgi'
2
+
3
+ module Kontent
4
+ module Ai
5
+ module Delivery
6
+ module QueryParameters
7
+ # Base class for all parameters added to a DeliveryQuery. All
8
+ # QueryParameters will appear in the query string.
9
+ class ParameterBase
10
+ attr_accessor :key
11
+ SEPARATOR = CGI::escape(',')
12
+
13
+ # Constructor.
14
+ #
15
+ # * *Args*:
16
+ # - *key* (+string+) The field to filter upon
17
+ # - *operator* (+string+) The Kontent.ai filter being applied to the field, in brackets
18
+ # - *values* (+Object+) One or more values which will appear as the value of the query string parameter
19
+ # - *eq_sign* (+boolean+) If false, the equals sign is not generated in the parameter
20
+ def initialize(key, operator, values, eq_sign = true)
21
+ self.key = key
22
+ values = [values] unless values.respond_to? :each
23
+ @values = values
24
+ @operator = operator
25
+ @eq_sign = eq_sign
26
+ end
27
+
28
+ # Converts the object into a valid query string parameter for use in
29
+ # a request to Delivery. The key, operator, and values are all escaped
30
+ # and if there are multiple values, they are joined with commas.
31
+ #
32
+ # * *Returns*:
33
+ # - +string+ A query string parameter without any additional characters (e.g. '&')
34
+ def provide_query_string_parameter
35
+ escaped_values = []
36
+ @values.each { |n| escaped_values << CGI.escape(n.to_s) }
37
+ if @eq_sign
38
+ format(
39
+ '%<k>s%<o>s=%<v>s',
40
+ k: CGI.escape(key),
41
+ o: CGI.escape(@operator),
42
+ v: escaped_values.join(SEPARATOR)
43
+ )
44
+ else
45
+ format(
46
+ '%<k>s%<o>s',
47
+ k: CGI.escape(key),
48
+ o: CGI.escape(@operator)
49
+ )
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,78 @@
1
+ require 'delivery/query_parameters/parameter_base'
2
+
3
+ module Kontent
4
+ module Ai
5
+ module Delivery
6
+ module QueryParameters
7
+ # Represents the entire query string for a request to Delivery.
8
+ class QueryString
9
+ def initialize
10
+ @params = []
11
+ end
12
+
13
+ # Adds a parameter to the query string
14
+ #
15
+ # * *Args*:
16
+ # - *param* (+Object+) Either a string representing the key for the parameter, or a complete Kontent::Ai::Delivery::QueryParameters::ParameterBase object
17
+ # - *values* (+string+) A string or array of strings representing the values for the parameter
18
+ # - *operator* (+string+) Kontent.ai filtering parameter, placed after the key, before the equal sign
19
+ def set_param(param, values = '', operator = '')
20
+ parameter_base =
21
+ if param.is_a? String
22
+ Kontent::Ai::Delivery::QueryParameters::ParameterBase.new(
23
+ param,
24
+ operator,
25
+ values
26
+ )
27
+ else
28
+ param
29
+ end
30
+ # Ensure we have a ParameterBase object
31
+ return unless parameter_base.respond_to? 'provide_query_string_parameter'
32
+
33
+ remove_param parameter_base.key
34
+ @params << parameter_base
35
+ end
36
+
37
+ # Removes all parameters from the query string with a matching key.
38
+ #
39
+ # * *Args*:
40
+ # - *key* (+string+) Parameter key
41
+ def remove_param(key)
42
+ @params.delete_if { |i| i.key.eql? key }
43
+ end
44
+
45
+ # Returns all parameters from the query string with a matching key.
46
+ #
47
+ # * *Args*:
48
+ # - *key* (+string+) Parameter key
49
+ #
50
+ # * *Returns*:
51
+ # - +Object+ One or more Kontent::Ai::Delivery::QueryParameters::ParameterBase objects
52
+ def param(key)
53
+ @params.select { |p| p.key.eql? key }
54
+ end
55
+
56
+ # Checks whether there are any parameters defined.
57
+ #
58
+ # * *Returns*:
59
+ # - +bool+ True if there are no parameters set.
60
+ def empty?
61
+ @params.empty?
62
+ end
63
+
64
+ # Generates a full query string based on the set parameters, with the
65
+ # required '?' character at the start. Accomplished by calling the
66
+ # Kontent::Ai::Delivery::QueryParameters::ParameterBase.provide_query_string_parameter
67
+ # method for each parameter.
68
+ #
69
+ # * *Returns*:
70
+ # - +string+ A complete query string
71
+ def to_s
72
+ '?' + @params.map(&:provide_query_string_parameter).join('&')
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,102 @@
1
+ require 'nokogiri'
2
+
3
+ module Kontent
4
+ module Ai
5
+ module Delivery
6
+ module Resolvers
7
+ # Locates <a data-item-id=""> tags in content and calls a user-defined method
8
+ # to supply the href for content item links.
9
+ # See https://github.com/kontent-ai/delivery-sdk-ruby#resolving-links
10
+ class ContentLinkResolver
11
+ # Constructor.
12
+ #
13
+ # * *Args*:
14
+ # - *found_handler* (+lambda+) _optional_ Method to be called when resolving a content link and the content item is present in the response
15
+ # - *not_found_handler* (+lambda+) _optional_ Method to be called when resolving a content link and the content item isn't present in the response
16
+ def initialize(found_handler = nil, not_found_handler = nil)
17
+ @found_handler = found_handler
18
+ @not_found = not_found_handler
19
+ end
20
+
21
+ # Resolves all links in the content.
22
+ #
23
+ # * *Args*:
24
+ # - *content* (+string+) The string value stored in the element
25
+ # - *links* (+Array+) The collection of links from an element's 'links' JSON node
26
+ #
27
+ # * *Returns*:
28
+ # - +string+ The original content passed, with all links resolved
29
+ def resolve(content, links)
30
+ doc = Nokogiri::HTML.parse(content).xpath('//body')
31
+ links = links.map { |link| ContentLink.new link }
32
+ tags = doc.xpath('//a[@data-item-id]')
33
+ # This line performs the link resolving and replaces the tags in doc
34
+ tags.map { |tag| resolve_tag tag, links }
35
+ doc.to_xhtml
36
+ end
37
+
38
+ private
39
+
40
+ # Accepts a tag found in the content and tries to locate matching
41
+ # source link from JSON response. If found, resolves URL and returns
42
+ # the tag with generated HREF.
43
+ #
44
+ # * *Args*:
45
+ # - *tag* (+string+) A <a data-item-id=""> tag found in the content
46
+ # - *links* (+Array+) The collection of links from an element's 'links' JSON node, converted to Kontent::Ai::Delivery::Resolvers::ContentLink objects
47
+ #
48
+ # * *Returns*:
49
+ # - +string+ The <a data-item-id=""> tag with an HREF generated by the +provide_url+ method
50
+ def resolve_tag(tag, links)
51
+ matches = links.select { |link| link.id == tag['data-item-id'].to_s }
52
+ url = provide_url matches, tag['data-item-id']
53
+ tag['href'] = url
54
+ tag
55
+ end
56
+
57
+ # Uses the +resolve_link+ method to generate a URL for a ContentLink
58
+ # object, or +resolve_404+ if the content item was not present in the
59
+ # response.
60
+ #
61
+ # * *Args*:
62
+ # - *matches* (+Array+) The ContentLink objects with an ID matching a particular <a data-item-id=""> tag
63
+ # - *id* (+string+) The ID of the <a data-item-id=""> tag being resolved
64
+ #
65
+ # * *Returns*:
66
+ # - +string+ A url to the item or 404 page
67
+ def provide_url(matches, id)
68
+ if matches.empty?
69
+ if @not_found_handler.nil?
70
+ resolve_404 id
71
+ else
72
+ @not_found_handler.call id
73
+ end
74
+ else
75
+ if @found_handler.nil?
76
+ resolve_link matches[0]
77
+ else
78
+ @found_handler.call matches[0]
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ # Model for links from the JSON response
85
+ class ContentLink
86
+ attr_accessor :code_name, :type, :url_slug, :id
87
+
88
+ # Constructor.
89
+ #
90
+ # * *Args*:
91
+ # - *link* (+JSON+) One link from an element's 'links' JSON node
92
+ def initialize(link)
93
+ self.id = link[0]
94
+ self.code_name = link[1]['codename']
95
+ self.type = link[1]['type']
96
+ self.url_slug = link[1]['url_slug']
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,75 @@
1
+ require 'nokogiri'
2
+
3
+ module Kontent
4
+ module Ai
5
+ module Delivery
6
+ module Resolvers
7
+ # Locates <object data-type="item"> tags in content and calls a user-defined
8
+ # method to supply the output for the content item.
9
+ # See https://github.com/kontent-ai/delivery-sdk-ruby#resolving-inline-content
10
+ class InlineContentItemResolver
11
+ def initialize(callback = nil)
12
+ @callback = callback
13
+ end
14
+
15
+ # Resolves all inline content items in the content.
16
+ #
17
+ # * *Args*:
18
+ # - *content* (+string+) The string value stored in the element
19
+ # - *inline_items* (+Array+) ContentItems referenced by the content from the 'modular_content' JSON node
20
+ #
21
+ # * *Returns*:
22
+ # - +string+ The original content passed, with all <object data-type="item"> replaced with custom output
23
+ def resolve(content, inline_items)
24
+ doc = Nokogiri::HTML.parse(content).xpath('//body')
25
+ tags = doc.xpath('//object[@type="application/kenticocloud"][@data-type="item"]')
26
+ tags.each do |tag|
27
+ output = resolve_tag tag, inline_items
28
+ el = doc.at_xpath(
29
+ '//object[@type="application/kenticocloud"][@data-type="item"][@data-codename=$value]',
30
+ nil,
31
+ value: tag['data-codename']
32
+ )
33
+ el.swap(output) unless output.nil?
34
+ end
35
+ doc.inner_html
36
+ end
37
+
38
+ private
39
+
40
+ # Accepts a tag found in the content and tries to locate matching
41
+ # ContentItem from JSON response.
42
+ #
43
+ # * *Args*:
44
+ # - *tag* (+string+) A <object data-type="item"> tag found in the content
45
+ # - *inline_items* (+Array+) ContentItems referenced by the content from the 'modular_content' JSON node
46
+ #
47
+ # * *Returns*:
48
+ # - +string+ The custom output generated by the +provide_output+ method
49
+ def resolve_tag(tag, inline_items)
50
+ matches = inline_items.select { |item| item.system.codename == tag['data-codename'].to_s }
51
+ provide_output matches
52
+ end
53
+
54
+ # Generates custom output for a content item using the +resolve_item+
55
+ # method.
56
+ #
57
+ # * *Args*:
58
+ # - *matches* (+Array+) The ContentItems from the 'modular_content' JSON node which match the code name of a particular <object data-type="item"> tag
59
+ #
60
+ # * *Returns*:
61
+ # - +string+ The custom output generated by the +resolve_item+ method
62
+ def provide_output(matches)
63
+ if !matches.empty?
64
+ if @callback.nil?
65
+ resolve_item matches[0]
66
+ else
67
+ @callback.call matches[0]
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,43 @@
1
+ module Kontent
2
+ module Ai
3
+ module Delivery
4
+ module Resolvers
5
+ # Resolves a content item by its codename. It contains the modular content
6
+ # of item/items response.
7
+ class LinkedItemResolver
8
+ def initialize(modular_content, content_link_url_resolver, inline_content_item_resolver)
9
+ @modular_content = modular_content
10
+ @content_link_url_resolver = content_link_url_resolver
11
+ @inline_content_item_resolver = inline_content_item_resolver
12
+ @resolved_items = {}
13
+ end
14
+
15
+ # Resolves a content item. If the link for a codename was resolved
16
+ # before, it returns the same instance of ContentItem.
17
+ #
18
+ # * *Args*:
19
+ # - *codename* (+string+) Codename of the content item
20
+ #
21
+ # * *Return*:
22
+ # - Kontent::Ai::Delivery::ContentItem
23
+ def resolve(codename)
24
+ @resolved_items[codename] ||= resolve_item(codename)
25
+ end
26
+
27
+ private
28
+
29
+ def resolve_item(codename)
30
+ item = @modular_content.values.find { |i| i['system']['codename'] == codename }
31
+ unless item.nil?
32
+ return ContentItem.new(JSON.parse(JSON.generate(item)),
33
+ @content_link_url_resolver,
34
+ @inline_content_item_resolver,
35
+ self)
36
+ end
37
+ nil
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,34 @@
1
+ require 'delivery/responses/response_base'
2
+
3
+ module Kontent
4
+ module Ai
5
+ module Delivery
6
+ module Responses
7
+ # The response of a successful query of a content type's element
8
+ # See https://github.com/kontent-ai/delivery-sdk-ruby#retrieving-content-type-elements
9
+ class DeliveryElementResponse < ResponseBase
10
+ # An element's definition from a
11
+ # Kontent::Ai::Delivery::DeliveryClient.element call
12
+ #
13
+ # * *Returns*:
14
+ # - +OpenStruct+ The element of a content item
15
+ def element
16
+ @element unless @element.nil?
17
+ @element = JSON.parse(
18
+ JSON.generate(@response),
19
+ object_class: OpenStruct
20
+ )
21
+ end
22
+
23
+ def initialize(headers, body)
24
+ @response = JSON.parse(body)
25
+ super 200,
26
+ "Success, '#{element.codename}' returned",
27
+ headers,
28
+ JSON.generate(@response)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,54 @@
1
+ require 'delivery/models/content_item'
2
+ require 'delivery/models/pagination'
3
+ require 'delivery/responses/response_base'
4
+
5
+ module Kontent
6
+ module Ai
7
+ module Delivery
8
+ module Responses
9
+ # The response of a successful query for content items.
10
+ # See https://github.com/kontent-ai/delivery-sdk-ruby#listing-items
11
+ class DeliveryItemListingResponse < ResponseBase
12
+ # Parses the 'pagination' JSON node of the response.
13
+ #
14
+ # * *Returns*:
15
+ # - Kontent::Ai::Delivery::Pagination
16
+ def pagination
17
+ @pagination unless @pagination.nil?
18
+ @pagination = Pagination.new @response['pagination']
19
+ end
20
+
21
+ # A collection of Kontent::Ai::Delivery::ContentItem objects from
22
+ # a Kontent::Ai::Delivery::DeliveryClient.items call.
23
+ #
24
+ # * *Returns*:
25
+ # - +Array+ One or more Kontent::Ai::Delivery::ContentItem objects
26
+ def items
27
+ @items unless @items.nil?
28
+ linked_items_resolver = Kontent::Ai::Delivery::Resolvers::LinkedItemResolver.new @response['modular_content'], @content_link_url_resolver, @inline_content_item_resolver
29
+ items = []
30
+ @response['items'].each do |n|
31
+ items << Kontent::Ai::Delivery::ContentItem.new(
32
+ n,
33
+ @content_link_url_resolver,
34
+ @inline_content_item_resolver,
35
+ linked_items_resolver
36
+ )
37
+ end
38
+ @items = items
39
+ end
40
+
41
+ def initialize(headers, body, query)
42
+ @response = JSON.parse(body)
43
+ @content_link_url_resolver = query.content_link_url_resolver
44
+ @inline_content_item_resolver = query.inline_content_item_resolver
45
+ super 200,
46
+ "Success, #{items.length} items returned",
47
+ headers,
48
+ JSON.generate(@response)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end