reactor_sdk 0.1.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 +7 -0
- data/CHANGELOG.md +19 -0
- data/LICENSE.txt +21 -0
- data/README.md +281 -0
- data/lib/reactor_sdk/authentication.rb +137 -0
- data/lib/reactor_sdk/client.rb +186 -0
- data/lib/reactor_sdk/configuration.rb +102 -0
- data/lib/reactor_sdk/connection.rb +342 -0
- data/lib/reactor_sdk/endpoints/app_configurations.rb +42 -0
- data/lib/reactor_sdk/endpoints/audit_events.rb +64 -0
- data/lib/reactor_sdk/endpoints/base_endpoint.rb +207 -0
- data/lib/reactor_sdk/endpoints/builds.rb +62 -0
- data/lib/reactor_sdk/endpoints/callbacks.rb +38 -0
- data/lib/reactor_sdk/endpoints/companies.rb +42 -0
- data/lib/reactor_sdk/endpoints/data_elements.rb +251 -0
- data/lib/reactor_sdk/endpoints/environments.rb +174 -0
- data/lib/reactor_sdk/endpoints/extension_package_usage_authorizations.rb +51 -0
- data/lib/reactor_sdk/endpoints/extension_packages.rb +63 -0
- data/lib/reactor_sdk/endpoints/extensions.rb +181 -0
- data/lib/reactor_sdk/endpoints/hosts.rb +101 -0
- data/lib/reactor_sdk/endpoints/libraries.rb +872 -0
- data/lib/reactor_sdk/endpoints/notes.rb +11 -0
- data/lib/reactor_sdk/endpoints/profiles.rb +14 -0
- data/lib/reactor_sdk/endpoints/properties.rb +123 -0
- data/lib/reactor_sdk/endpoints/revisions.rb +102 -0
- data/lib/reactor_sdk/endpoints/rule_components.rb +218 -0
- data/lib/reactor_sdk/endpoints/rules.rb +240 -0
- data/lib/reactor_sdk/endpoints/search.rb +23 -0
- data/lib/reactor_sdk/endpoints/secrets.rb +76 -0
- data/lib/reactor_sdk/error.rb +115 -0
- data/lib/reactor_sdk/library_comparison_builder.rb +74 -0
- data/lib/reactor_sdk/library_snapshot_builder.rb +66 -0
- data/lib/reactor_sdk/paginator.rb +92 -0
- data/lib/reactor_sdk/rate_limiter.rb +96 -0
- data/lib/reactor_sdk/reference_extractor.rb +34 -0
- data/lib/reactor_sdk/resource_metadata.rb +73 -0
- data/lib/reactor_sdk/resource_normalizer.rb +90 -0
- data/lib/reactor_sdk/resources/app_configuration.rb +20 -0
- data/lib/reactor_sdk/resources/audit_event.rb +45 -0
- data/lib/reactor_sdk/resources/base_resource.rb +181 -0
- data/lib/reactor_sdk/resources/build.rb +64 -0
- data/lib/reactor_sdk/resources/callback.rb +16 -0
- data/lib/reactor_sdk/resources/company.rb +38 -0
- data/lib/reactor_sdk/resources/comprehensive_data_element.rb +28 -0
- data/lib/reactor_sdk/resources/comprehensive_extension.rb +30 -0
- data/lib/reactor_sdk/resources/comprehensive_resource.rb +31 -0
- data/lib/reactor_sdk/resources/comprehensive_rule.rb +26 -0
- data/lib/reactor_sdk/resources/comprehensive_upstream_chain.rb +50 -0
- data/lib/reactor_sdk/resources/comprehensive_upstream_chain_entry.rb +34 -0
- data/lib/reactor_sdk/resources/data_element.rb +108 -0
- data/lib/reactor_sdk/resources/environment.rb +45 -0
- data/lib/reactor_sdk/resources/extension.rb +66 -0
- data/lib/reactor_sdk/resources/extension_package.rb +49 -0
- data/lib/reactor_sdk/resources/extension_package_usage_authorization.rb +26 -0
- data/lib/reactor_sdk/resources/host.rb +68 -0
- data/lib/reactor_sdk/resources/library.rb +67 -0
- data/lib/reactor_sdk/resources/library_comparison.rb +72 -0
- data/lib/reactor_sdk/resources/library_comparison_entry.rb +144 -0
- data/lib/reactor_sdk/resources/library_snapshot.rb +118 -0
- data/lib/reactor_sdk/resources/library_snapshot_extension_index.rb +70 -0
- data/lib/reactor_sdk/resources/library_snapshot_index.rb +169 -0
- data/lib/reactor_sdk/resources/library_with_resources.rb +194 -0
- data/lib/reactor_sdk/resources/note.rb +37 -0
- data/lib/reactor_sdk/resources/profile.rb +22 -0
- data/lib/reactor_sdk/resources/property.rb +44 -0
- data/lib/reactor_sdk/resources/revision.rb +156 -0
- data/lib/reactor_sdk/resources/rule.rb +44 -0
- data/lib/reactor_sdk/resources/rule_component.rb +101 -0
- data/lib/reactor_sdk/resources/search_results.rb +28 -0
- data/lib/reactor_sdk/resources/secret.rb +17 -0
- data/lib/reactor_sdk/resources/upstream_chain.rb +80 -0
- data/lib/reactor_sdk/resources/upstream_chain_entry.rb +55 -0
- data/lib/reactor_sdk/response_parser.rb +160 -0
- data/lib/reactor_sdk/version.rb +5 -0
- data/lib/reactor_sdk.rb +79 -0
- data/reactor_sdk.gemspec +70 -0
- data/sig/reactor_sdk.rbs +346 -0
- metadata +293 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# @file endpoints/base_endpoint.rb
|
|
5
|
+
# @description Base class for all Reactor API endpoint groups.
|
|
6
|
+
#
|
|
7
|
+
# Provides three shared dependencies to every endpoint subclass:
|
|
8
|
+
# - connection for making authenticated HTTP calls
|
|
9
|
+
# - paginator for fetching all pages of list endpoints
|
|
10
|
+
# - parser for converting JSON:API hashes into typed resources
|
|
11
|
+
#
|
|
12
|
+
# Also provides two protected helper methods used by every endpoint:
|
|
13
|
+
# - build_payload builds a JSON:API write payload (POST/PATCH)
|
|
14
|
+
# - build_relationship_payload builds a JSON:API relationship payload
|
|
15
|
+
#
|
|
16
|
+
# Every endpoint class inherits from this and focuses only on its
|
|
17
|
+
# own resource domain — it never touches HTTP or pagination directly.
|
|
18
|
+
#
|
|
19
|
+
# @domain Endpoints
|
|
20
|
+
#
|
|
21
|
+
|
|
22
|
+
module ReactorSDK
|
|
23
|
+
module Endpoints
|
|
24
|
+
class BaseEndpoint
|
|
25
|
+
##
|
|
26
|
+
# @param connection [ReactorSDK::Connection] Authenticated HTTP client
|
|
27
|
+
# @param paginator [ReactorSDK::Paginator] Handles cursor pagination
|
|
28
|
+
# @param parser [ReactorSDK::ResponseParser] Converts JSON:API to resources
|
|
29
|
+
#
|
|
30
|
+
def initialize(connection:, paginator:, parser:)
|
|
31
|
+
@connection = connection
|
|
32
|
+
@paginator = paginator
|
|
33
|
+
@parser = parser
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
protected
|
|
37
|
+
|
|
38
|
+
##
|
|
39
|
+
# Builds a JSON:API compliant request payload for create and update requests.
|
|
40
|
+
#
|
|
41
|
+
# POST (create) — omit the id parameter:
|
|
42
|
+
# build_payload("properties", { name: "My Site", platform: "web" })
|
|
43
|
+
# => { data: { type: "properties", attributes: { name: "My Site", platform: "web" } } }
|
|
44
|
+
#
|
|
45
|
+
# PATCH (update) — include the id parameter:
|
|
46
|
+
# build_payload("properties", { name: "New Name" }, id: "PR123")
|
|
47
|
+
# => { data: { id: "PR123", type: "properties", attributes: { name: "New Name" } } }
|
|
48
|
+
#
|
|
49
|
+
# @param type [String] JSON:API resource type (e.g. "properties")
|
|
50
|
+
# @param attributes [Hash] Resource attribute values to send
|
|
51
|
+
# @param id [String, nil] Resource ID — required for PATCH, omit for POST
|
|
52
|
+
# @param relationships [Hash, nil] JSON:API relationships payload
|
|
53
|
+
# @param meta [Hash, nil] JSON:API meta payload
|
|
54
|
+
# @return [Hash] Correctly structured JSON:API payload
|
|
55
|
+
#
|
|
56
|
+
def build_payload(type, attributes, id: nil, relationships: nil, meta: nil)
|
|
57
|
+
data = { type: type, attributes: attributes }
|
|
58
|
+
data[:id] = id if id
|
|
59
|
+
data[:relationships] = relationships if relationships
|
|
60
|
+
data[:meta] = meta if meta
|
|
61
|
+
{ data: data }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
##
|
|
65
|
+
# Builds a JSON:API relationship payload for associating resources.
|
|
66
|
+
# Used when adding rules, data elements, or extensions to a library.
|
|
67
|
+
#
|
|
68
|
+
# @example Add two rules to a library
|
|
69
|
+
# build_relationship_payload("rules", ["RL123", "RL456"])
|
|
70
|
+
# => { data: [{ id: "RL123", type: "rules" }, { id: "RL456", type: "rules" }] }
|
|
71
|
+
#
|
|
72
|
+
# @param type [String] JSON:API resource type
|
|
73
|
+
# @param ids [Array<String>] Array of Adobe resource IDs to associate
|
|
74
|
+
# @return [Hash] JSON:API relationship payload
|
|
75
|
+
#
|
|
76
|
+
def build_relationship_payload(type, ids)
|
|
77
|
+
{
|
|
78
|
+
data: Array(ids).map { |id| { id: id, type: type } }
|
|
79
|
+
}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
##
|
|
83
|
+
# Fetches and parses a single related resource.
|
|
84
|
+
#
|
|
85
|
+
# @param path [String]
|
|
86
|
+
# @param resource_class [Class]
|
|
87
|
+
# @param params [Hash]
|
|
88
|
+
# @return [Object]
|
|
89
|
+
#
|
|
90
|
+
def fetch_resource(path, resource_class, params: {})
|
|
91
|
+
response = @connection.get(path, params: params)
|
|
92
|
+
@parser.parse(response['data'], resource_class, response: response)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
##
|
|
96
|
+
# Fetches and parses a related resource collection.
|
|
97
|
+
#
|
|
98
|
+
# @param path [String]
|
|
99
|
+
# @param resource_class [Class]
|
|
100
|
+
# @param params [Hash]
|
|
101
|
+
# @return [Array<Object>]
|
|
102
|
+
#
|
|
103
|
+
def list_resources(path, resource_class, params: {})
|
|
104
|
+
records = @paginator.all(path, params: params)
|
|
105
|
+
@parser.parse_many(records, resource_class)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
##
|
|
109
|
+
# Fetches and parses a heterogeneous resource collection using
|
|
110
|
+
# each record's JSON:API type to choose the SDK class.
|
|
111
|
+
#
|
|
112
|
+
# @param path [String]
|
|
113
|
+
# @param params [Hash]
|
|
114
|
+
# @return [Array<ReactorSDK::Resources::BaseResource>]
|
|
115
|
+
#
|
|
116
|
+
def list_resources_auto(path, params: {})
|
|
117
|
+
records = @paginator.all(path, params: params)
|
|
118
|
+
@parser.parse_many_auto(records)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
##
|
|
122
|
+
# Creates and parses a single resource.
|
|
123
|
+
#
|
|
124
|
+
# @param path [String]
|
|
125
|
+
# @param type [String]
|
|
126
|
+
# @param resource_class [Class]
|
|
127
|
+
# @param attributes [Hash]
|
|
128
|
+
# @param relationships [Hash, nil]
|
|
129
|
+
# @param meta [Hash, nil]
|
|
130
|
+
# @return [Object]
|
|
131
|
+
#
|
|
132
|
+
def create_resource(path, type, resource_class, attributes:, relationships: nil, meta: nil)
|
|
133
|
+
payload = build_payload(type, attributes, relationships: relationships, meta: meta)
|
|
134
|
+
response = @connection.post(path, payload)
|
|
135
|
+
@parser.parse(response['data'], resource_class, response: response)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
##
|
|
139
|
+
# Updates and parses a single resource.
|
|
140
|
+
#
|
|
141
|
+
# @param path [String]
|
|
142
|
+
# @param id [String]
|
|
143
|
+
# @param type [String]
|
|
144
|
+
# @param resource_class [Class]
|
|
145
|
+
# @param attributes [Hash]
|
|
146
|
+
# @param relationships [Hash, nil]
|
|
147
|
+
# @param meta [Hash, nil]
|
|
148
|
+
# @return [Object]
|
|
149
|
+
#
|
|
150
|
+
def update_resource(path, id, type, resource_class, attributes:, relationships: nil, meta: nil)
|
|
151
|
+
payload = build_payload(
|
|
152
|
+
type,
|
|
153
|
+
attributes,
|
|
154
|
+
id: id,
|
|
155
|
+
relationships: relationships,
|
|
156
|
+
meta: meta
|
|
157
|
+
)
|
|
158
|
+
response = @connection.patch(path, payload)
|
|
159
|
+
@parser.parse(response['data'], resource_class, response: response)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
##
|
|
163
|
+
# Deletes a resource and normalizes the nil return value.
|
|
164
|
+
#
|
|
165
|
+
# @param path [String]
|
|
166
|
+
# @return [nil]
|
|
167
|
+
#
|
|
168
|
+
def delete_resource(path)
|
|
169
|
+
@connection.delete(path)
|
|
170
|
+
nil
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
##
|
|
174
|
+
# Fetches raw relationship linkage data.
|
|
175
|
+
#
|
|
176
|
+
# @param path [String]
|
|
177
|
+
# @param params [Hash]
|
|
178
|
+
# @return [Hash, Array<Hash>, nil]
|
|
179
|
+
#
|
|
180
|
+
def fetch_relationship(path, params: {})
|
|
181
|
+
response = @connection.get(path, params: params)
|
|
182
|
+
response['data']
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
##
|
|
186
|
+
# Creates a note under a notable resource.
|
|
187
|
+
#
|
|
188
|
+
# @param path [String]
|
|
189
|
+
# @param text [String]
|
|
190
|
+
# @return [ReactorSDK::Resources::Note]
|
|
191
|
+
#
|
|
192
|
+
def create_note_for_path(path, text)
|
|
193
|
+
create_resource(path, 'notes', Resources::Note, attributes: { text: text })
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
##
|
|
197
|
+
# Lists note resources for a notable resource path.
|
|
198
|
+
#
|
|
199
|
+
# @param path [String]
|
|
200
|
+
# @return [Array<ReactorSDK::Resources::Note>]
|
|
201
|
+
#
|
|
202
|
+
def list_notes_for_path(path)
|
|
203
|
+
list_resources(path, Resources::Note)
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# @file endpoints/builds.rb
|
|
5
|
+
# @description Endpoint group for Adobe Launch Build resources.
|
|
6
|
+
#
|
|
7
|
+
# Builds are the compiled output of a library — the JavaScript bundle
|
|
8
|
+
# deployed to an environment. LaunchGuard polls build status after
|
|
9
|
+
# triggering a build to detect success or failure before notifying users.
|
|
10
|
+
#
|
|
11
|
+
# @domain Endpoints
|
|
12
|
+
# @see https://developer.adobe.com/experience-platform/documentation/tags/api/endpoints/builds/
|
|
13
|
+
#
|
|
14
|
+
|
|
15
|
+
module ReactorSDK
|
|
16
|
+
module Endpoints
|
|
17
|
+
class Builds < BaseEndpoint
|
|
18
|
+
##
|
|
19
|
+
# Retrieves a single build by its Adobe ID.
|
|
20
|
+
# Used to poll build status after a build is triggered.
|
|
21
|
+
#
|
|
22
|
+
# @param build_id [String] Adobe build ID (format: "BL" + hex string)
|
|
23
|
+
# @return [ReactorSDK::Resources::Build]
|
|
24
|
+
# @raise [ReactorSDK::ResourceNotFoundError] if the build does not exist
|
|
25
|
+
#
|
|
26
|
+
def find(build_id)
|
|
27
|
+
response = @connection.get("/builds/#{build_id}")
|
|
28
|
+
@parser.parse(response['data'], Resources::Build)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# Lists all builds for a given library.
|
|
33
|
+
# Follows pagination automatically — returns all builds.
|
|
34
|
+
#
|
|
35
|
+
# @param library_id [String] Adobe library ID
|
|
36
|
+
# @return [Array<ReactorSDK::Resources::Build>]
|
|
37
|
+
# @raise [ReactorSDK::ResourceNotFoundError] if the library does not exist
|
|
38
|
+
#
|
|
39
|
+
def list_for_library(library_id)
|
|
40
|
+
records = @paginator.all("/libraries/#{library_id}/builds")
|
|
41
|
+
records.map { |r| @parser.parse(r, Resources::Build) }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
##
|
|
45
|
+
# Republishes an existing build.
|
|
46
|
+
#
|
|
47
|
+
# @param build_id [String]
|
|
48
|
+
# @return [ReactorSDK::Resources::Build]
|
|
49
|
+
#
|
|
50
|
+
def republish(build_id)
|
|
51
|
+
update_resource(
|
|
52
|
+
"/builds/#{build_id}",
|
|
53
|
+
build_id,
|
|
54
|
+
'builds',
|
|
55
|
+
Resources::Build,
|
|
56
|
+
attributes: {},
|
|
57
|
+
meta: { action: 'republish' }
|
|
58
|
+
)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ReactorSDK
|
|
4
|
+
module Endpoints
|
|
5
|
+
class Callbacks < BaseEndpoint
|
|
6
|
+
def list_for_property(property_id)
|
|
7
|
+
list_resources("/properties/#{property_id}/callbacks", Resources::Callback)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def find(callback_id)
|
|
11
|
+
fetch_resource("/callbacks/#{callback_id}", Resources::Callback)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create(property_id:, attributes:)
|
|
15
|
+
create_resource(
|
|
16
|
+
"/properties/#{property_id}/callbacks",
|
|
17
|
+
'callbacks',
|
|
18
|
+
Resources::Callback,
|
|
19
|
+
attributes: attributes
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def update(callback_id, attributes)
|
|
24
|
+
update_resource(
|
|
25
|
+
"/callbacks/#{callback_id}",
|
|
26
|
+
callback_id,
|
|
27
|
+
'callbacks',
|
|
28
|
+
Resources::Callback,
|
|
29
|
+
attributes: attributes
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def delete(callback_id)
|
|
34
|
+
delete_resource("/callbacks/#{callback_id}")
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# @file endpoints/companies.rb
|
|
5
|
+
# @description Endpoint group for Adobe Launch Company resources.
|
|
6
|
+
#
|
|
7
|
+
# A Company maps to an Adobe IMS Organisation and is the top-level
|
|
8
|
+
# container for all properties. Most orgs have exactly one company.
|
|
9
|
+
#
|
|
10
|
+
# @domain Endpoints
|
|
11
|
+
# @see https://developer.adobe.com/experience-platform/documentation/tags/api/endpoints/companies/
|
|
12
|
+
#
|
|
13
|
+
|
|
14
|
+
module ReactorSDK
|
|
15
|
+
module Endpoints
|
|
16
|
+
class Companies < BaseEndpoint
|
|
17
|
+
##
|
|
18
|
+
# Lists all companies accessible to the authenticated token.
|
|
19
|
+
# Follows pagination automatically — returns all companies.
|
|
20
|
+
#
|
|
21
|
+
# @return [Array<ReactorSDK::Resources::Company>]
|
|
22
|
+
# @raise [ReactorSDK::AuthorizationError] if the token lacks access
|
|
23
|
+
#
|
|
24
|
+
def list
|
|
25
|
+
records = @paginator.all('/companies')
|
|
26
|
+
records.map { |r| @parser.parse(r, Resources::Company) }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# Retrieves a single company by its Adobe ID.
|
|
31
|
+
#
|
|
32
|
+
# @param company_id [String] Adobe company ID (format: "CO" + hex string)
|
|
33
|
+
# @return [ReactorSDK::Resources::Company]
|
|
34
|
+
# @raise [ReactorSDK::ResourceNotFoundError] if the company does not exist
|
|
35
|
+
#
|
|
36
|
+
def find(company_id)
|
|
37
|
+
response = @connection.get("/companies/#{company_id}")
|
|
38
|
+
@parser.parse(response['data'], Resources::Company)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# @file endpoints/data_elements.rb
|
|
5
|
+
# @description Endpoint group for Adobe Launch Data Element resources.
|
|
6
|
+
#
|
|
7
|
+
# Data elements are reusable values that can be referenced throughout
|
|
8
|
+
# rules and other data elements. They form the data layer of Adobe Launch.
|
|
9
|
+
#
|
|
10
|
+
# Creating a data element requires an extension relationship in the payload.
|
|
11
|
+
# Fetch the property's extensions first to obtain the extension_id.
|
|
12
|
+
#
|
|
13
|
+
# Important: data elements must be revised before they can be added to
|
|
14
|
+
# a library. Call revise(data_element_id) before libraries.add_data_elements.
|
|
15
|
+
#
|
|
16
|
+
# @domain Endpoints
|
|
17
|
+
# @see https://developer.adobe.com/experience-platform/documentation/tags/api/endpoints/data-elements/
|
|
18
|
+
#
|
|
19
|
+
|
|
20
|
+
module ReactorSDK
|
|
21
|
+
module Endpoints
|
|
22
|
+
class DataElements < BaseEndpoint
|
|
23
|
+
##
|
|
24
|
+
# Lists all data elements for a given property.
|
|
25
|
+
# Follows pagination automatically — returns all data elements.
|
|
26
|
+
#
|
|
27
|
+
# @param property_id [String] Adobe property ID
|
|
28
|
+
# @return [Array<ReactorSDK::Resources::DataElement>]
|
|
29
|
+
# @raise [ReactorSDK::ResourceNotFoundError] if the property does not exist
|
|
30
|
+
#
|
|
31
|
+
def list_for_property(property_id)
|
|
32
|
+
records = @paginator.all("/properties/#{property_id}/data_elements")
|
|
33
|
+
records.map { |r| @parser.parse(r, Resources::DataElement) }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
# Retrieves a single data element by its Adobe ID.
|
|
38
|
+
#
|
|
39
|
+
# @param data_element_id [String] Adobe data element ID (format: "DE" + hex)
|
|
40
|
+
# @return [ReactorSDK::Resources::DataElement]
|
|
41
|
+
# @raise [ReactorSDK::ResourceNotFoundError] if the data element does not exist
|
|
42
|
+
#
|
|
43
|
+
def find(data_element_id)
|
|
44
|
+
response = @connection.get("/data_elements/#{data_element_id}")
|
|
45
|
+
@parser.parse(response['data'], Resources::DataElement)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
##
|
|
49
|
+
# Creates a new data element within a property.
|
|
50
|
+
#
|
|
51
|
+
# Requires an extension_id — fetch the property's extensions first:
|
|
52
|
+
# extensions = client.extensions.list_for_property(property_id)
|
|
53
|
+
# extension_id = extensions.find { |e| e.delegate_descriptor_id.start_with?("core::") }.id
|
|
54
|
+
#
|
|
55
|
+
# The settings field must be a JSON-encoded string matching the delegate
|
|
56
|
+
# schema. For Core custom code the settings schema only allows "source" —
|
|
57
|
+
# do NOT include "language":
|
|
58
|
+
# settings: JSON.generate({ source: "return document.title;" })
|
|
59
|
+
#
|
|
60
|
+
# @param property_id [String] Adobe property ID
|
|
61
|
+
# @param name [String] Display name
|
|
62
|
+
# @param delegate_descriptor_id [String] Extension delegate identifier
|
|
63
|
+
# @param settings [String] JSON-encoded settings string
|
|
64
|
+
# @param extension_id [String] Adobe extension ID
|
|
65
|
+
# @param enabled [Boolean] Whether enabled (default: true)
|
|
66
|
+
# @return [ReactorSDK::Resources::DataElement]
|
|
67
|
+
# @raise [ReactorSDK::UnprocessableEntityError] if attributes are invalid
|
|
68
|
+
#
|
|
69
|
+
def create(
|
|
70
|
+
property_id:,
|
|
71
|
+
name:,
|
|
72
|
+
delegate_descriptor_id:,
|
|
73
|
+
settings:,
|
|
74
|
+
extension_id:,
|
|
75
|
+
enabled: true
|
|
76
|
+
)
|
|
77
|
+
payload = build_data_element_payload(
|
|
78
|
+
name, delegate_descriptor_id, settings, extension_id, enabled
|
|
79
|
+
)
|
|
80
|
+
response = @connection.post("/properties/#{property_id}/data_elements", payload)
|
|
81
|
+
@parser.parse(response['data'], Resources::DataElement)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
##
|
|
85
|
+
# Updates an existing data element.
|
|
86
|
+
#
|
|
87
|
+
# @param data_element_id [String] Adobe data element ID
|
|
88
|
+
# @param attributes [Hash] Fields to update
|
|
89
|
+
# @return [ReactorSDK::Resources::DataElement]
|
|
90
|
+
# @raise [ReactorSDK::ResourceNotFoundError] if the data element does not exist
|
|
91
|
+
#
|
|
92
|
+
def update(data_element_id, attributes)
|
|
93
|
+
payload = build_payload('data_elements', attributes, id: data_element_id)
|
|
94
|
+
response = @connection.patch("/data_elements/#{data_element_id}", payload)
|
|
95
|
+
@parser.parse(response['data'], Resources::DataElement)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
##
|
|
99
|
+
# Revises a data element so it can be added to a library.
|
|
100
|
+
#
|
|
101
|
+
# Adobe Launch requires every resource to be explicitly revised before
|
|
102
|
+
# it can be added to a library.
|
|
103
|
+
#
|
|
104
|
+
# Always call revise after create or update, before libraries.add_data_elements.
|
|
105
|
+
#
|
|
106
|
+
# @param data_element_id [String] Adobe data element ID
|
|
107
|
+
# @return [ReactorSDK::Resources::DataElement] The revised data element
|
|
108
|
+
# @raise [ReactorSDK::ResourceNotFoundError] if the data element does not exist
|
|
109
|
+
#
|
|
110
|
+
def revise(data_element_id)
|
|
111
|
+
payload = {
|
|
112
|
+
data: {
|
|
113
|
+
id: data_element_id,
|
|
114
|
+
type: 'data_elements',
|
|
115
|
+
meta: { action: 'revise' }
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
response = @connection.patch("/data_elements/#{data_element_id}", payload)
|
|
119
|
+
@parser.parse(response['data'], Resources::DataElement)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
##
|
|
123
|
+
# Deletes a data element permanently.
|
|
124
|
+
#
|
|
125
|
+
# @param data_element_id [String] Adobe data element ID
|
|
126
|
+
# @return [nil]
|
|
127
|
+
# @raise [ReactorSDK::ResourceNotFoundError] if the data element does not exist
|
|
128
|
+
#
|
|
129
|
+
def delete(data_element_id)
|
|
130
|
+
@connection.delete("/data_elements/#{data_element_id}")
|
|
131
|
+
nil
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
##
|
|
135
|
+
# Resolves the data element across the ordered upstream library chain.
|
|
136
|
+
#
|
|
137
|
+
# @param data_element_or_id [String, ReactorSDK::Resources::DataElement]
|
|
138
|
+
# @param library_id [String] Adobe library ID used as the comparison root
|
|
139
|
+
# @param property_id [String] Adobe property ID containing the library chain
|
|
140
|
+
# @return [ReactorSDK::Resources::UpstreamChain]
|
|
141
|
+
#
|
|
142
|
+
def upstream_chain(data_element_or_id, library_id:, property_id:)
|
|
143
|
+
libraries_endpoint.upstream_chain_for_resource(
|
|
144
|
+
data_element_or_id,
|
|
145
|
+
library_id: library_id,
|
|
146
|
+
property_id: property_id,
|
|
147
|
+
resource_type: 'data_elements'
|
|
148
|
+
)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
##
|
|
152
|
+
# Fetches the data element from a library-context review snapshot
|
|
153
|
+
# together with impact analysis and normalized review payload.
|
|
154
|
+
#
|
|
155
|
+
# @param data_element_id [String]
|
|
156
|
+
# @param library_id [String]
|
|
157
|
+
# @param property_id [String]
|
|
158
|
+
# @return [ReactorSDK::Resources::ComprehensiveDataElement]
|
|
159
|
+
#
|
|
160
|
+
def find_comprehensive(data_element_id, library_id:, property_id:)
|
|
161
|
+
snapshot = libraries_endpoint.find_snapshot(library_id, property_id: property_id)
|
|
162
|
+
comprehensive = snapshot.comprehensive_resource(data_element_id, resource_type: 'data_elements')
|
|
163
|
+
unless comprehensive
|
|
164
|
+
raise ReactorSDK::ResourceNotFoundError,
|
|
165
|
+
"Data element #{data_element_id} was not found in library #{library_id}"
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
comprehensive
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
##
|
|
172
|
+
# Resolves the data element across the ordered upstream chain using
|
|
173
|
+
# snapshot-aware comprehensive review objects.
|
|
174
|
+
#
|
|
175
|
+
# @param data_element_or_id [String, ReactorSDK::Resources::DataElement]
|
|
176
|
+
# @param library_id [String]
|
|
177
|
+
# @param property_id [String]
|
|
178
|
+
# @return [ReactorSDK::Resources::ComprehensiveUpstreamChain]
|
|
179
|
+
#
|
|
180
|
+
def comprehensive_upstream_chain(data_element_or_id, library_id:, property_id:)
|
|
181
|
+
libraries_endpoint.comprehensive_upstream_chain_for_resource(
|
|
182
|
+
data_element_or_id,
|
|
183
|
+
library_id: library_id,
|
|
184
|
+
property_id: property_id,
|
|
185
|
+
resource_type: 'data_elements'
|
|
186
|
+
)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
##
|
|
190
|
+
# Lists notes attached to a data element.
|
|
191
|
+
#
|
|
192
|
+
# @param data_element_id [String]
|
|
193
|
+
# @return [Array<ReactorSDK::Resources::Note>]
|
|
194
|
+
#
|
|
195
|
+
def list_notes(data_element_id)
|
|
196
|
+
list_notes_for_path("/data_elements/#{data_element_id}/notes")
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
##
|
|
200
|
+
# Creates a note on a data element.
|
|
201
|
+
#
|
|
202
|
+
# @param data_element_id [String]
|
|
203
|
+
# @param text [String]
|
|
204
|
+
# @return [ReactorSDK::Resources::Note]
|
|
205
|
+
#
|
|
206
|
+
def create_note(data_element_id, text)
|
|
207
|
+
create_note_for_path("/data_elements/#{data_element_id}/notes", text)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
private
|
|
211
|
+
|
|
212
|
+
##
|
|
213
|
+
# Builds the JSON:API payload for data element creation.
|
|
214
|
+
# Includes the required extension relationship.
|
|
215
|
+
#
|
|
216
|
+
# @param name [String] Display name
|
|
217
|
+
# @param delegate_descriptor_id [String] Delegate identifier
|
|
218
|
+
# @param settings [String] JSON-encoded settings
|
|
219
|
+
# @param extension_id [String] Extension providing the delegate
|
|
220
|
+
# @param enabled [Boolean] Whether enabled
|
|
221
|
+
# @return [Hash] JSON:API compliant payload
|
|
222
|
+
#
|
|
223
|
+
def build_data_element_payload(name, delegate_descriptor_id, settings, extension_id, enabled)
|
|
224
|
+
{
|
|
225
|
+
data: {
|
|
226
|
+
type: 'data_elements',
|
|
227
|
+
attributes: {
|
|
228
|
+
name: name,
|
|
229
|
+
delegate_descriptor_id: delegate_descriptor_id,
|
|
230
|
+
settings: settings,
|
|
231
|
+
enabled: enabled
|
|
232
|
+
},
|
|
233
|
+
relationships: {
|
|
234
|
+
extension: {
|
|
235
|
+
data: { id: extension_id, type: 'extensions' }
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def libraries_endpoint
|
|
243
|
+
@libraries_endpoint ||= Endpoints::Libraries.new(
|
|
244
|
+
connection: @connection,
|
|
245
|
+
paginator: @paginator,
|
|
246
|
+
parser: @parser
|
|
247
|
+
)
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|