zendesk_apps_support 4.43.0 → 4.44.0.alpha.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb1263460bfbe9c194c8fda9e78daf072564bef7a21aedb306de03b559ce5421
4
- data.tar.gz: ddabccda72e04ab33db2a26175ca262da66981b683b1a1c5160553d14b59ebfd
3
+ metadata.gz: b611098add00d4e6f1c03e6604521db85f49bd6beea30a43695a286c0d474122
4
+ data.tar.gz: 40e1ade02e50ac1980eeda60def6501368499e48f46c6180f5e5e7f0053564e2
5
5
  SHA512:
6
- metadata.gz: 44bc5bd9f53ed9a6b3d7ddd41fa235056967e5cd53a6b8e6a12cd5cc27e69e4cf3314e8f2b318cc336d182295965aa14f54b29de8d923915b2aec4bc007ea8a3
7
- data.tar.gz: faaa6f86ad8e7cf652853817570b8b56b3fc27121a8d6c6451b4c07492582432a7794929d2dbe9890639883a017628ea8eda1c0afda0dcecf114d2ad18f53fa8
6
+ metadata.gz: 7052e5b47f7b72d52073f25e39291ef32b0373d850b4912d1f82b05a7463188e328452823471bde20ffa537d1bb47ffb53a5ad50713343114423352d3a0861d8
7
+ data.tar.gz: 8010184c5735b90149c78a3f75ba4d29a08e90f5d4ed0eebda6f94f16763ceeb08328671ef273355492f53a9b931802a253b0be0879fa4969f00c6beddc36ec6
@@ -105,6 +105,133 @@ parts:
105
105
  title: "App builder job: requirements file contains too many custom objects requirements. Leave requirements.json as is (do not localize)"
106
106
  value: "The requirements.json file contains too many custom objects requirements. The current limit is %{max} requirements. This app has %{count} requirements."
107
107
  screenshot: "https://drive.google.com/open?id=18yac8rV7kMe5qm49ERVFVCA7WOZl8vcP"
108
+ - translation:
109
+ key: "txt.apps.admin.error.app_build.excessive_custom_objects_v2_requirements"
110
+ title: "App builder job: requirements file contains too many custom objects v2 requirements. The maximum number of custom objects per account is 50. Leave requirements.json as is (do not translate)"
111
+ value: "The requirements.json file contains too many custom objects v2 requirements. The current limit is %{max} custom objects per account. This app has %{count} custom objects per account."
112
+ screenshot: "https://drive.google.com/file/d/1eFZWrESblrmgJxp8ls0rk1RPkDxJ0w-4/view?usp=sharing"
113
+ - translation:
114
+ key: "txt.apps.admin.error.app_build.excessive_custom_objects_v2_fields"
115
+ title: "App builder job: requirements file contains too many custom object fields. The maximum number of custom object fields per object is 10. Leave requirements.json as is (do not translate)"
116
+ value: "The requirements.json file contains too many custom object fields. The current limit is %{max} fields per custom object. This app has %{count} fields for object %{object_key}."
117
+ screenshot: "https://drive.google.com/file/d/1mEiQLJxTb-lFFnVt96n051w4BnxJOZID/view?usp=sharing"
118
+ - translation:
119
+ key: "txt.apps.admin.error.app_build.excessive_custom_objects_v2_triggers"
120
+ title: "App builder job: requirements file contains too many custom object triggers. The maximum number of custom object triggers per object is 20. Leave requirements.json as is (do not translate)"
121
+ value: "The requirements.json file contains too many custom object triggers. The current limit is %{max} triggers per custom object. This app has %{count} triggers for object %{object_key}."
122
+ screenshot: "https://drive.google.com/file/d/1JTEmjrUTq7Bsxoy36Syj-vhbkG8W_68D/view?usp=sharing"
123
+ - translation:
124
+ key: "txt.apps.admin.error.app_build.excessive_custom_objects_v2_trigger_conditions"
125
+ title: "App builder job: requirements file contains too many custom object trigger conditions. The maximum number of conditions allowed per trigger is 50. Leave requirements.json as is (do not translate)"
126
+ value: "The requirements.json file contains too many custom object trigger conditions. The current limit is %{max} conditions per trigger. This app has %{count} conditions for trigger %{trigger_title}."
127
+ screenshot: "https://drive.google.com/file/d/1szSaYRTeIcHux5nMJg3Yxyct1Obxa-wv/view?usp=sharing"
128
+ - translation:
129
+ key: "txt.apps.admin.error.app_build.excessive_custom_objects_v2_trigger_actions"
130
+ title: "App builder job: requirements file contains too many custom object trigger actions. The maximum number of actions allowed per trigger is 25. Leave requirements.json as is (do not translate)"
131
+ value: "The requirements.json file contains too many custom object trigger actions. The current limit is %{max} actions per trigger. This app has %{count} actions for trigger %{trigger_title}."
132
+ screenshot: "https://drive.google.com/file/d/18jXaM7_OnPqHAg6jAxJrTrgX1v_H156_/view?usp=sharing"
133
+ - translation:
134
+ key: "txt.apps.admin.error.app_build.excessive_cov2_dropdown_fields_per_object"
135
+ title: "App builder job: requirements file contains too many custom object fields of type dropdown. The maximum number of fields of type dropdown per object is 5. Leave requirements.json as is (do not translate)"
136
+ value: "The requirements.json file contains too many custom object fields of type dropdown. The current limit is %{max} fields per object. This app has %{count} fields of type dropdown for object %{object_key}."
137
+ screenshot: "https://drive.google.com/file/d/1hILvdZQXZCtkQVupYXedPbnD_rNN4nwH/view?usp=sharing"
138
+ obsolete: "2025-11-01"
139
+ - translation:
140
+ key: "txt.apps.admin.error.app_build.excessive_cov2_multiselect_fields_per_object"
141
+ title: "App builder job: requirements file contains too many custom object fields of type multiselect. The maximum number of fields of type multiselect per object is 5. Leave requirements.json as is (do not translate)"
142
+ value: "The requirements.json file contains too many custom object fields of type multiselect. The current limit is %{max} fields per object. This app has %{count} fields of type multiselect for object %{object_key}."
143
+ screenshot: "https://drive.google.com/file/d/1RJgWEKXv7Zkt7V2Vh3QZyl55W9QOC6Z9/view?usp=sharing"
144
+ obsolete: "2025-11-01"
145
+ - translation:
146
+ key: "txt.apps.admin.error.app_build.excessive_cov2_field_options"
147
+ title: "App builder job: requirements file contains too many options for custom object field of type dropdown or multiselect. The maximum number of options of type dropdown or multiselect per field is 10. Leave requirements.json as is (do not translate)"
148
+ value: "The requirements.json file contains too many options for custom object field %{field_key}. The current limit is %{max} options per field. This app has %{count} options for field %{field_key} in object %{object_key}."
149
+ screenshot: "https://drive.google.com/file/d/1ipP9khKzDdaDxWgKT1WyBG2D2c8HPc0P/view?usp=sharing"
150
+ - translation:
151
+ key: "txt.apps.admin.error.app_build.excessive_cov2_relationship_filter_conditions"
152
+ title: "App builder job: requirements file contains too many conditions in relationship filter for lookup fields. The maximum number of conditions allowed in the relationship filter per field is 20. Leave requirements.json as is (do not translate)"
153
+ value: "The requirements.json file contains too many conditions in relationship filter for custom object field %{field_key}. The current limit is %{max} conditions per field. This app has %{count} conditions for field %{field_key} in object %{object_key}."
154
+ "screenshot": "https://drive.google.com/file/d/13J6GIkq3CXGqRwV5KRHouXulRVuwQnNi/view?usp=sharing"
155
+ - translation:
156
+ key: "txt.apps.admin.error.app_build.missing_cov2_object_schema_key"
157
+ title: 'App builder job: requirements file is missing a custom object schema key. These are the required keys: (key, title, title_pluralized, include_in_list_view). The term \"schema key\" typically refers to an identifier or attribute that defines a specific item within a schema and it should be translated. Leave requirements.json as is (do not translate)'
158
+ value: "The requirements.json file is missing custom object schema key for object %{object_key}. The following key is required: %{missing_key}."
159
+ "screenshot": "https://drive.google.com/file/d/15iZemfkt14z96W4zmDHw1kodU70UxMYs/view?usp=sharing"
160
+ - translation:
161
+ key: "txt.apps.admin.error.app_build.missing_cov2_field_schema_key"
162
+ title: 'App builder job: requirements file is missing a custom object field schema key. These are the required keys: (key, title, type, object_key). The term \"schema key\" typically refers to an identifier or attribute that defines a specific item within a schema and it should be translated. Leave requirements.json as is (do not translate)'
163
+ value: "The requirements.json file is missing custom object field schema key for field %{field_key} in object %{object_key}. The following key is required: %{missing_key}."
164
+ "screenshot": "https://drive.google.com/file/d/1hYqJ_df8jhjqQjUQHMAC-yrAK7uGaKEH/view?usp=sharing"
165
+ - translation:
166
+ key: "txt.apps.admin.error.app_build.missing_cov2_trigger_schema_key"
167
+ title: 'App builder job: requirements file is missing a custom object trigger schema key. These are the required keys: (title, actions, conditions, object_key). The term \"schema key\" typically refers to an identifier or attribute that defines a specific item within a schema and it should be translated. Leave requirements.json as is (do not translate)'
168
+ value: "The requirements.json file is missing custom object trigger schema key for trigger %{trigger_title} in object %{object_key}. The following key is required: %{missing_key}."
169
+ "screenshot": "https://drive.google.com/file/d/1Q_qFDZMoUzfAdL27QehW0q1rrHG3BPcP/view?usp=sharing"
170
+ - translation:
171
+ key: "txt.apps.admin.error.app_build.empty_cov2_trigger_conditions"
172
+ title: "App builder job: requirements file contains an empty conditions array for custom object trigger. Leave requirements.json as is (do not translate)"
173
+ value: "The requirements.json file contains an empty conditions array for custom object trigger %{trigger_title} in object %{object_key}."
174
+ "screenshot": "https://drive.google.com/file/d/1dU534_37__yrqX9lQujjgTJeCV5Y5FIp/view?usp=sharing"
175
+ - translation:
176
+ key: "txt.apps.admin.error.app_build.invalid_cov2_requirements_structure"
177
+ title: 'App builder job: requirements file contains invalid custom objects v2 structure. An "object" here refers to a programming object (a set of key-value pairs), not a custom object in Zendesk. Leave requirements.json, custom_objects_v2 as is (do not translate)'
178
+ value: 'The requirements.json file contains an invalid custom_objects_v2 structure. \"custom_objects_v2\" requirements must be an object.'
179
+ screenshot: "https://drive.google.com/file/d/1_P5Vl_QikPs-WgxqgDKJdgQW3jr1pTk2/view?usp=sharing"
180
+ - translation:
181
+ key: "txt.apps.admin.error.app_build.excessive_cov2_payload_size"
182
+ title: "App builder job: requirements file contains custom objects v2 payload that exceeds maximum size limit. The maximum payload size is 1 MB. Leave requirements.json as is (do not translate)"
183
+ value: "The requirements.json file contains a custom objects v2 payload that is too large. The maximum allowed size is 1 MB."
184
+ screenshot: "https://drive.google.com/file/d/1buZhVxCslyX3fYiqJPWgJrWZyW3oHbGg/view?usp=sharing"
185
+ - translation:
186
+ key: "txt.apps.admin.error.app_build.invalid_cov2_trigger_conditions_structure"
187
+ title: 'App builder job: requirements file contains invalid custom object trigger conditions structure. Conditions must be an object (a set of key-value pairs, like { "all": [], "any": [] } in JSON) with "all" and "any" arrays as keys. Leave requirements.json, "all" and "any" as is (do not translate)'
188
+ value: 'The requirements.json file contains an invalid custom object trigger conditions structure. Conditions must be a hash with "all" and "any" arrays for trigger %{trigger_title}.'
189
+ screenshot: "https://drive.google.com/file/d/1c4Hgk8OXscco_cwOfCX5r8Ub3k_-umrr/view?usp=sharing"
190
+ - translation:
191
+ key: "txt.apps.admin.error.app_build.invalid_cov2_trigger_actions_structure"
192
+ title: "App builder job: requirements file contains an invalid custom object trigger actions structure. Actions must be an array. 'actions' is part of requirements file. Leave requirements.json and 'actions' as is (do not translate)"
193
+ value: 'The requirements.json file contains an invalid custom object trigger actions structure. \"actions\" must be an array for trigger %{trigger_title}.'
194
+ screenshot: "https://drive.google.com/file/d/12p8LzIcK4-ItJfHqHQiTaKxDxWnIiDni/view?usp=sharing"
195
+ - translation:
196
+ key: "txt.apps.admin.error.app_build.empty_cov2_trigger_actions"
197
+ title: "App builder job: requirements file contains empty custom object trigger actions. At least one action must be specified. Leave requirements.json as is (do not translate)"
198
+ value: "The requirements.json file contains empty custom object trigger actions. At least one action must be specified for trigger %{trigger_title}."
199
+ screenshot: "https://drive.google.com/file/d/12XxGTNfRwh0aQM0gJkc_gFxiYSB0Op_r/view?usp=sharing"
200
+ - translation:
201
+ key: "txt.apps.admin.error.app_build.excessive_cov2_selection_fields_per_object"
202
+ title: "App builder job: requirements file contains too many custom object fields of type dropdown or multiselect. The maximum number of fields of type dropdown or multiselect per object is 5. Leave requirements.json as is (do not translate). If your language has concatenation issues, please translate as: The requirements.json file contains too many custom object fields of type %{field_type}. The current limit per object is %{max}. This app has object %{object_key}, which has %{count} fields of type %{field_type}."
203
+ value: "The requirements.json file contains too many custom object fields of type %{field_type}. The current limit is %{max} fields per object. This app has %{count} fields of type %{field_type} for object %{object_key}."
204
+ screenshot: "https://drive.google.com/file/d/1hILvdZQXZCtkQVupYXedPbnD_rNN4nwH/view?usp=sharing"
205
+ - translation:
206
+ key: "txt.apps.admin.error.app_build.invalid_objects_structure_in_cov2_requirements"
207
+ title: "App builder job: requirements file contains invalid objects structure for custom objects v2. Objects must be an array. Leave requirements.json and 'objects' as is (do not translate)"
208
+ value: 'The requirements.json file contains an invalid objects structure. \"objects\" must be an array.'
209
+ screenshot: "https://drive.google.com/file/d/1_0TOE9hOP2XeGZNyw9ueiYspvWGLileu/view?usp=sharing"
210
+ - translation:
211
+ key: "txt.apps.admin.error.app_build.invalid_object_fields_structure_in_cov2_requirements"
212
+ title: "App builder job: requirements file contains invalid object_fields structure for custom objects v2. Object_fields must be an array. Leave requirements.json and 'object_fields' as is (do not translate)"
213
+ value: 'The requirements.json file contains an invalid object_fields structure. \"object_fields\" must be an array.'
214
+ screenshot: "https://drive.google.com/file/d/1yIHf-no1xXobSxnhmBuZSqzFMbZROzDO/view?usp=sharing"
215
+ - translation:
216
+ key: "txt.apps.admin.error.app_build.invalid_object_triggers_structure_in_cov2_requirements"
217
+ title: "App builder job: requirements file contains invalid object_triggers structure for custom objects v2. Object_triggers must be an array. Leave requirements.json and 'object_triggers' as is (do not translate)"
218
+ value: 'The requirements.json file contains an invalid object_triggers structure. \"object_triggers\" must be an array.'
219
+ screenshot: "https://drive.google.com/file/d/14NNUm9R0u45LPbugUNmpA9psEwED1zkB/view?usp=sharing"
220
+ - translation:
221
+ key: "txt.apps.admin.error.app_build.empty_cov2_requirements"
222
+ title: "App builder job: requirements file contains an empty hash for custom objects v2. Leave requirements.json as is (do not translate)"
223
+ value: "The requirements.json file contains empty custom objects v2 requirements. You must define valid requirements."
224
+ screenshot: "https://drive.google.com/file/d/1AfbKu_JOMSG9274IUrIUvwirSuwbxy3Y/view?usp=sharing"
225
+ - translation:
226
+ key: "txt.apps.admin.error.app_build.invalid_cov2_object_reference_in_fields"
227
+ title: 'App builder job: requirements file contains an invalid object reference in object_fields for Custom Objects V2. Do not translate "requirements.json", "object_fields", \"%{item_identifier}\", \"%{object_key}\".'
228
+ value: 'The requirements.json file contains an invalid object reference in object_fields. Field \"%{item_identifier}\" references object \"%{object_key}\" which does not exist in the objects array.'
229
+ screenshot: "https://drive.google.com/file/d/124uX-MBnEoqt7lDZBqQb4OVT2YN8-qz2/view?usp=sharing"
230
+ - translation:
231
+ key: "txt.apps.admin.error.app_build.invalid_cov2_object_reference_in_triggers"
232
+ title: 'App builder job: requirements file contains an invalid object reference in object_triggers for Custom Objects V2. Do not translate "requirements.json", "object_fields", \"%{item_identifier}\", \"%{object_key}\".'
233
+ value: 'The requirements.json file contains an invalid object reference in object_triggers. Trigger \"%{item_identifier}\" references object \"%{object_key}\" which does not exist in the objects array.'
234
+ screenshot: "https://drive.google.com/file/d/11e3x1sEfXQydkE-mRQ_rHqqLCRurHoCN/view?usp=sharing"
108
235
  - translation:
109
236
  key: "txt.apps.admin.error.app_build.missing_required_fields"
110
237
  title: "App builder job: required key missing in requirements, e.g. \"title\" is required in \"my_custom_email_target\""
@@ -6,7 +6,8 @@ module ZendeskAppsSupport
6
6
  CUSTOM_OBJECTS_KEY = 'custom_objects'
7
7
  CUSTOM_OBJECTS_TYPE_KEY = 'custom_object_types'
8
8
  CUSTOM_OBJECTS_RELATIONSHIP_TYPE_KEY = 'custom_object_relationship_types'
9
+ CUSTOM_OBJECTS_V2_KEY = 'custom_objects_v2'
9
10
  TYPES = %w[automations channel_integrations custom_objects macros targets views ticket_fields
10
- triggers user_fields organization_fields webhooks].freeze
11
+ triggers user_fields organization_fields webhooks custom_objects_v2].freeze
11
12
  end
12
13
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ZendeskAppsSupport
4
+ module Validations
5
+ module CustomObjectsV2
6
+ module Constants
7
+ MAX_OBJECTS = 50
8
+ MAX_FIELDS_PER_OBJECT = 10
9
+ MAX_TRIGGERS_PER_OBJECT = 20
10
+ MAX_CONDITIONS_PER_TRIGGER = 50
11
+ MAX_ACTIONS_PER_TRIGGER = 25
12
+ MAX_CONDITIONS_IN_RELATIONSHIP_FILTER_PER_OBJECT = 20
13
+ MAX_DROPDOWN_FIELDS_PER_OBJECT = 5
14
+ MAX_MULTISELECT_FIELDS_PER_OBJECT = 5
15
+ MAX_DROPDOWN_OPTIONS_PER_FIELD = 10
16
+ MAX_MULTISELECT_OPTIONS_PER_FIELD = 10
17
+
18
+ SCHEMA_KEYS = {
19
+ objects: 'objects',
20
+ object_fields: 'object_fields',
21
+ object_triggers: 'object_triggers'
22
+ }.freeze
23
+
24
+ OBJECT_KEY = 'object_key'
25
+ TYPE = 'type'
26
+ KEY = 'key'
27
+ TITLE = 'title'
28
+ CF_OPTIONS = 'custom_field_options'
29
+ RELATIONSHIP_FILTER = 'relationship_filter'
30
+ DROPDOWN = 'dropdown'
31
+ MULTISELECT = 'multiselect'
32
+ CONDITIONS = 'conditions'
33
+ ACTIONS = 'actions'
34
+ ALL = 'all'
35
+ ANY = 'any'
36
+
37
+ SELECTION_FIELD_LIMITS = {
38
+ DROPDOWN => MAX_DROPDOWN_FIELDS_PER_OBJECT,
39
+ MULTISELECT => MAX_MULTISELECT_FIELDS_PER_OBJECT
40
+ }.freeze
41
+
42
+ SELECTION_FIELD_OPTIONS_LIMITS = {
43
+ DROPDOWN => MAX_DROPDOWN_OPTIONS_PER_FIELD,
44
+ MULTISELECT => MAX_MULTISELECT_OPTIONS_PER_FIELD
45
+ }.freeze
46
+
47
+ UNDEFINED_VALUE = '(undefined)'
48
+ CONDITION_KEYS = [ALL, ANY].freeze
49
+ MAX_PAYLOAD_SIZE_BYTES = 1_048_576 # 1 MB in bytes
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'constants'
4
+ require_relative 'limits_validator'
5
+ require_relative 'schema_validator'
6
+ require_relative 'validation_helpers'
7
+
8
+ module ZendeskAppsSupport
9
+ module Validations
10
+ module CustomObjectsV2
11
+ class << self
12
+ include Constants
13
+
14
+ def call(requirements)
15
+ errors = validate_overall_requirements_structure(requirements)
16
+ return errors if errors.any?
17
+
18
+ payload_size_errors = validate_payload_size(requirements)
19
+ return payload_size_errors if payload_size_errors.any?
20
+
21
+ [
22
+ validate_limits(requirements),
23
+ validate_schema(requirements)
24
+ ].flatten
25
+ end
26
+
27
+ private
28
+
29
+ def validate_payload_size(requirements)
30
+ payload_size = requirements.to_json.bytesize
31
+ return [] if payload_size <= MAX_PAYLOAD_SIZE_BYTES
32
+
33
+ [ValidationError.new(:excessive_cov2_payload_size)]
34
+ end
35
+
36
+ def validate_overall_requirements_structure(requirements)
37
+ errors = validate_structural_requirements(requirements)
38
+ return errors unless errors.empty?
39
+
40
+ objects = requirements[SCHEMA_KEYS[:objects]]
41
+ object_fields = requirements[SCHEMA_KEYS[:object_fields]]
42
+ object_triggers = requirements[SCHEMA_KEYS[:object_triggers]]
43
+
44
+ if all_collections_empty?(objects, object_fields, object_triggers)
45
+ return [ValidationError.new(:empty_cov2_requirements)]
46
+ end
47
+
48
+ [
49
+ validate_collection_is_array(objects, :invalid_objects_structure_in_cov2_requirements),
50
+ validate_collection_is_array(object_fields, :invalid_object_fields_structure_in_cov2_requirements),
51
+ validate_collection_is_array(object_triggers, :invalid_object_triggers_structure_in_cov2_requirements)
52
+ ].flatten
53
+ end
54
+
55
+ def validate_structural_requirements(requirements)
56
+ return [ValidationError.new(:invalid_cov2_requirements_structure)] unless requirements.is_a?(Hash)
57
+ return [ValidationError.new(:empty_cov2_requirements)] if requirements.empty?
58
+
59
+ []
60
+ end
61
+
62
+ def validate_limits(requirements)
63
+ LimitsValidator.validate(requirements)
64
+ end
65
+
66
+ def validate_schema(requirements)
67
+ SchemaValidator.validate(requirements)
68
+ end
69
+
70
+ def validate_collection_is_array(collection, error_type)
71
+ return [] if collection.nil? || collection.is_a?(Array)
72
+
73
+ [ValidationError.new(error_type)]
74
+ end
75
+
76
+ def all_collections_empty?(objects, object_fields, object_triggers)
77
+ [objects, object_fields, object_triggers].all? do |collection|
78
+ collection.is_a?(Array) && collection.empty?
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,183 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'validation_helpers'
4
+ require_relative 'constants'
5
+
6
+ module ZendeskAppsSupport
7
+ module Validations
8
+ module CustomObjectsV2
9
+ class LimitsValidator
10
+ class << self
11
+ include ValidationHelpers
12
+ include Constants
13
+ def validate(requirements)
14
+ [
15
+ validate_objects_excessive_limit(requirements[SCHEMA_KEYS[:objects]]),
16
+ validate_fields_excessive_limit(requirements[SCHEMA_KEYS[:object_fields]]),
17
+ validate_triggers_excessive_limit(requirements[SCHEMA_KEYS[:object_triggers]])
18
+ ].flatten
19
+ end
20
+
21
+ private
22
+
23
+ def validate_objects_excessive_limit(objects)
24
+ return [] if objects.nil? || objects.size <= MAX_OBJECTS
25
+
26
+ [ValidationError.new(:excessive_custom_objects_v2_requirements,
27
+ max: MAX_OBJECTS,
28
+ count: objects.size)]
29
+ end
30
+
31
+ def validate_fields_excessive_limit(object_fields)
32
+ valid_fields = extract_hash_entries(object_fields).reject do |field|
33
+ field[OBJECT_KEY].to_s.empty?
34
+ end
35
+
36
+ [
37
+ validate_fields_limit(valid_fields),
38
+ validate_selection_field_limits(valid_fields),
39
+ validate_field_options_limits(valid_fields),
40
+ validate_relationship_filter_limits(valid_fields)
41
+ ].flatten
42
+ end
43
+
44
+ def validate_fields_limit(object_fields)
45
+ validation_context = { max_limit: MAX_FIELDS_PER_OBJECT,
46
+ error: :excessive_custom_objects_v2_fields }
47
+ validate_collection_limits(object_fields, **validation_context)
48
+ end
49
+
50
+ def validate_selection_field_limits(object_fields)
51
+ SELECTION_FIELD_LIMITS.flat_map do |field_type, max_limit|
52
+ filtered_fields = object_fields.select { |field| field[TYPE] == field_type }
53
+ validate_field_type_limit(filtered_fields, field_type, max_limit)
54
+ end
55
+ end
56
+
57
+ def validate_field_type_limit(object_fields, field_type, max_limit)
58
+ validation_context = { max_limit: max_limit,
59
+ error: :excessive_cov2_selection_fields_per_object,
60
+ field_type: field_type }
61
+
62
+ validate_collection_limits(object_fields, **validation_context)
63
+ end
64
+
65
+ def validate_field_options_limits(object_fields)
66
+ SELECTION_FIELD_OPTIONS_LIMITS.flat_map do |field_type, max_limit|
67
+ validate_options_limit(object_fields, field_type, max_limit)
68
+ end
69
+ end
70
+
71
+ def validate_options_limit(object_fields, field_type, max_limit)
72
+ fields_with_options = object_fields.select do |field|
73
+ field[TYPE] == field_type && field[CF_OPTIONS]&.any?
74
+ end
75
+
76
+ fields_with_options.filter_map do |field|
77
+ options = field[CF_OPTIONS]
78
+
79
+ next if options.size <= max_limit
80
+
81
+ ValidationError.new(:excessive_cov2_field_options,
82
+ max: max_limit,
83
+ count: options.size,
84
+ field_key: field[KEY],
85
+ object_key: field[OBJECT_KEY])
86
+ end
87
+ end
88
+
89
+ def validate_relationship_filter_limits(object_fields)
90
+ object_fields
91
+ .select { |field| field[RELATIONSHIP_FILTER] }
92
+ .flat_map { |field| validate_relationship_filter_conditions(field) }
93
+ end
94
+
95
+ def validate_relationship_filter_conditions(field)
96
+ relationship_filter = field[RELATIONSHIP_FILTER]
97
+ return [] unless relationship_filter
98
+
99
+ total_conditions = count_conditions(relationship_filter)
100
+
101
+ return [] unless total_conditions > MAX_CONDITIONS_IN_RELATIONSHIP_FILTER_PER_OBJECT
102
+
103
+ [ValidationError.new(:excessive_cov2_relationship_filter_conditions,
104
+ max: MAX_CONDITIONS_IN_RELATIONSHIP_FILTER_PER_OBJECT,
105
+ count: total_conditions,
106
+ field_key: field[KEY],
107
+ object_key: field[OBJECT_KEY])]
108
+ end
109
+
110
+ def validate_triggers_excessive_limit(object_triggers = [])
111
+ valid_triggers = extract_hash_entries(object_triggers).reject do |trigger|
112
+ trigger[OBJECT_KEY].to_s.empty?
113
+ end
114
+ return [] unless valid_triggers&.any?
115
+
116
+ [
117
+ validate_triggers_limit(valid_triggers),
118
+ validate_triggers_conditions_limit(valid_triggers),
119
+ validate_triggers_actions_limit(valid_triggers)
120
+ ].flatten
121
+ end
122
+
123
+ def validate_triggers_limit(object_triggers)
124
+ validation_context = { max_limit: MAX_TRIGGERS_PER_OBJECT,
125
+ error: :excessive_custom_objects_v2_triggers }
126
+
127
+ validate_collection_limits(object_triggers, **validation_context)
128
+ end
129
+
130
+ def validate_triggers_conditions_limit(object_triggers)
131
+ object_triggers.flat_map do |trigger|
132
+ validate_trigger_conditions(trigger)
133
+ end
134
+ end
135
+
136
+ def validate_trigger_conditions(trigger)
137
+ return [] unless trigger[CONDITIONS].is_a?(Hash)
138
+
139
+ total_conditions = count_conditions(trigger[CONDITIONS])
140
+
141
+ return [] unless total_conditions > MAX_CONDITIONS_PER_TRIGGER
142
+
143
+ [ValidationError.new(:excessive_custom_objects_v2_trigger_conditions,
144
+ max: MAX_CONDITIONS_PER_TRIGGER,
145
+ count: total_conditions,
146
+ trigger_title: trigger[TITLE])]
147
+ end
148
+
149
+ def validate_triggers_actions_limit(object_triggers)
150
+ object_triggers.filter_map do |trigger|
151
+ next unless trigger[ACTIONS]
152
+
153
+ actions = trigger[ACTIONS]
154
+ next if actions.size <= MAX_ACTIONS_PER_TRIGGER
155
+
156
+ ValidationError.new(:excessive_custom_objects_v2_trigger_actions,
157
+ max: MAX_ACTIONS_PER_TRIGGER,
158
+ count: actions.size,
159
+ trigger_title: trigger[TITLE])
160
+ end
161
+ end
162
+
163
+ def validate_collection_limits(collection, **context)
164
+ grouped_items = collection.group_by { |item| item[OBJECT_KEY] }
165
+
166
+ grouped_items.filter_map do |object_key, items|
167
+ next if items.size <= context[:max_limit]
168
+
169
+ extra_context = context.except(:max_limit, :error)
170
+ validation_context = {
171
+ max: context[:max_limit],
172
+ count: items.size,
173
+ object_key: object_key,
174
+ **extra_context
175
+ }
176
+ ValidationError.new(context[:error], validation_context)
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'validation_helpers'
4
+ require_relative 'constants'
5
+
6
+ module ZendeskAppsSupport
7
+ module Validations
8
+ module CustomObjectsV2
9
+ class SchemaValidator
10
+ class << self
11
+ include ValidationHelpers
12
+ include Constants
13
+
14
+ def validate(requirements)
15
+ [
16
+ validate_objects_schema(requirements[SCHEMA_KEYS[:objects]]),
17
+ validate_fields_schema(requirements[SCHEMA_KEYS[:object_fields]]),
18
+ validate_triggers_schema(requirements[SCHEMA_KEYS[:object_triggers]])
19
+ ].flatten
20
+ end
21
+
22
+ private
23
+
24
+ def validate_objects_schema(objects = [])
25
+ valid_objects = extract_hash_entries(objects)
26
+ valid_objects.flat_map { |object| validate_object_schema(object) }
27
+ end
28
+
29
+ def validate_object_schema(object)
30
+ required_keys = %w[key title title_pluralized include_in_list_view]
31
+ missing_keys = required_keys - object.keys
32
+
33
+ missing_keys.map do |missing_key|
34
+ ValidationError.new(:missing_cov2_object_schema_key,
35
+ missing_key: missing_key,
36
+ object_key: safe_value(object[KEY]))
37
+ end
38
+ end
39
+
40
+ def validate_fields_schema(object_fields = [])
41
+ valid_fields = extract_hash_entries(object_fields)
42
+ valid_fields.flat_map { |field| validate_field_schema(field) }
43
+ end
44
+
45
+ def validate_field_schema(field)
46
+ required_keys = %w[key title type object_key]
47
+ missing_keys = required_keys - field.keys
48
+
49
+ missing_keys.map do |missing_key|
50
+ ValidationError.new(:missing_cov2_field_schema_key,
51
+ missing_key: missing_key,
52
+ field_key: safe_value(field[KEY]),
53
+ object_key: safe_value(field[OBJECT_KEY]))
54
+ end
55
+ end
56
+
57
+ def validate_triggers_schema(object_triggers = [])
58
+ valid_triggers = extract_hash_entries(object_triggers)
59
+ valid_triggers.flat_map { |trigger| validate_trigger_schema(trigger) }
60
+ end
61
+
62
+ def validate_trigger_schema(trigger)
63
+ required_keys = %w[object_key title actions conditions]
64
+ missing_keys = required_keys - trigger.keys
65
+ trigger_title = safe_value(trigger[TITLE])
66
+ object_key = safe_value(trigger[OBJECT_KEY])
67
+
68
+ errors = missing_keys.map do |missing_key|
69
+ ValidationError.new(:missing_cov2_trigger_schema_key,
70
+ missing_key: missing_key,
71
+ trigger_title: trigger_title,
72
+ object_key: object_key)
73
+ end
74
+
75
+ errors.concat(validate_conditions_schema(trigger[CONDITIONS], object_key, trigger_title))
76
+ errors.concat(validate_actions_schema(trigger[ACTIONS], object_key, trigger_title))
77
+ errors
78
+ end
79
+
80
+ def validate_conditions_schema(conditions, object_key, title)
81
+ error_data = { trigger_title: title, object_key: object_key }
82
+
83
+ unless valid_conditions_structure?(conditions)
84
+ return [ValidationError.new(:invalid_cov2_trigger_conditions_structure, **error_data)]
85
+ end
86
+
87
+ if count_conditions(conditions).zero?
88
+ return [ValidationError.new(:empty_cov2_trigger_conditions, **error_data)]
89
+ end
90
+
91
+ []
92
+ end
93
+
94
+ def validate_actions_schema(actions, object_key, title)
95
+ error_data = { trigger_title: title, object_key: object_key }
96
+
97
+ unless actions.is_a?(Array)
98
+ return [ValidationError.new(:invalid_cov2_trigger_actions_structure, **error_data)]
99
+ end
100
+
101
+ return [] unless actions.empty?
102
+
103
+ [ValidationError.new(:empty_cov2_trigger_actions, **error_data)]
104
+ end
105
+
106
+ def safe_value(value)
107
+ value || UNDEFINED_VALUE
108
+ end
109
+
110
+ def valid_conditions_structure?(conditions)
111
+ return false unless conditions.is_a?(Hash) && conditions.any?
112
+ return false if (conditions.keys - CONDITION_KEYS).any?
113
+
114
+ conditions.values.any? { |v| v.is_a?(Array) }
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ZendeskAppsSupport
4
+ module Validations
5
+ module CustomObjectsV2
6
+ module ValidationHelpers
7
+ private
8
+
9
+ def extract_hash_entries(collection)
10
+ return [] unless collection&.any?
11
+
12
+ collection.select { |item| item.is_a?(Hash) }
13
+ end
14
+
15
+ def count_conditions(conditions)
16
+ return 0 unless conditions.is_a?(Hash)
17
+
18
+ Constants::CONDITION_KEYS.sum { |key| conditions[key]&.size || 0 }
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -22,7 +22,7 @@ module ZendeskAppsSupport
22
22
  return [ValidationError.new(:missing_manifest)]
23
23
  end
24
24
 
25
- package.warnings << password_parameter_warning unless error_on_password_parameter
25
+ package.warnings << password_parameter_warning if !error_on_password_parameter && password_param_present?(package.manifest)
26
26
 
27
27
  collate_manifest_errors(package, error_on_password_parameter)
28
28
  rescue JSON::ParserError => e
@@ -33,6 +33,10 @@ module ZendeskAppsSupport
33
33
 
34
34
  private
35
35
 
36
+ def password_param_present?(manifest)
37
+ manifest.parameters.any? { |p| p.type == 'password' }
38
+ end
39
+
36
40
  def collate_manifest_errors(package, error_on_password_parameter)
37
41
  manifest = package.manifest
38
42
 
@@ -214,7 +218,7 @@ module ZendeskAppsSupport
214
218
 
215
219
  def deprecate_password_parameter_type(manifest)
216
220
  secure_settings_link = 'https://developer.zendesk.com/documentation/apps/app-developer-guide/making-api-requests-from-a-zendesk-app/#using-secure-settings'
217
- if manifest.parameters.any? { |p| p.type == 'password' }
221
+ if password_param_present?(manifest)
218
222
  ValidationError.new(:password_parameter_type_deprecated, link: secure_settings_link)
219
223
  end
220
224
  end
@@ -31,6 +31,7 @@ module ZendeskAppsSupport
31
31
  errors << invalid_custom_objects(requirements)
32
32
  errors << invalid_webhooks(requirements)
33
33
  errors << invalid_target_types(requirements)
34
+ errors << validate_custom_objects_v2_requirements(requirements)
34
35
  errors << missing_required_fields(requirements)
35
36
  errors.flatten!
36
37
  errors.compact!
@@ -48,9 +49,11 @@ module ZendeskAppsSupport
48
49
  def missing_required_fields(requirements)
49
50
  [].tap do |errors|
50
51
  requirements.each do |requirement_type, requirement|
51
- next if %w[channel_integrations custom_objects webhooks].include? requirement_type
52
+ next if %w[channel_integrations custom_objects webhooks custom_objects_v2].include? requirement_type
53
+
52
54
  requirement.each do |identifier, fields|
53
55
  next if fields.nil? || fields.include?('title')
56
+
54
57
  errors << ValidationError.new(:missing_required_fields,
55
58
  field: 'title',
56
59
  identifier: identifier)
@@ -77,6 +80,13 @@ module ZendeskAppsSupport
77
80
  end
78
81
  end
79
82
 
83
+ def validate_custom_objects_v2_requirements(requirements)
84
+ return unless requirements.key?(AppRequirement::CUSTOM_OBJECTS_V2_KEY)
85
+
86
+ cov2_requirements = requirements[AppRequirement::CUSTOM_OBJECTS_V2_KEY]
87
+ CustomObjectsV2.call(cov2_requirements)
88
+ end
89
+
80
90
  def invalid_custom_fields(requirements)
81
91
  user_fields = requirements['user_fields']
82
92
  organization_fields = requirements['organization_fields']
@@ -1,3 +1,3 @@
1
1
  module ZendeskAppsSupport
2
- VERSION = "4.43.0"
2
+ VERSION = "4.44.0.alpha.1"
3
3
  end
@@ -32,6 +32,7 @@ module ZendeskAppsSupport
32
32
  autoload :Requests, 'zendesk_apps_support/validations/requests'
33
33
  autoload :Banner, 'zendesk_apps_support/validations/banner'
34
34
  autoload :Svg, 'zendesk_apps_support/validations/svg'
35
+ autoload :CustomObjectsV2, 'zendesk_apps_support/validations/custom_objects_v2/custom_objects_v2'
35
36
  end
36
37
 
37
38
  class Manifest
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zendesk_apps_support
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.43.0
4
+ version: 4.44.0.alpha.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - James A. Rosen
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2025-07-15 00:00:00.000000000 Z
14
+ date: 2025-09-19 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: i18n
@@ -321,6 +321,11 @@ files:
321
321
  - lib/zendesk_apps_support/sass_functions.rb
322
322
  - lib/zendesk_apps_support/stylesheet_compiler.rb
323
323
  - lib/zendesk_apps_support/validations/banner.rb
324
+ - lib/zendesk_apps_support/validations/custom_objects_v2/constants.rb
325
+ - lib/zendesk_apps_support/validations/custom_objects_v2/custom_objects_v2.rb
326
+ - lib/zendesk_apps_support/validations/custom_objects_v2/limits_validator.rb
327
+ - lib/zendesk_apps_support/validations/custom_objects_v2/schema_validator.rb
328
+ - lib/zendesk_apps_support/validations/custom_objects_v2/validation_helpers.rb
324
329
  - lib/zendesk_apps_support/validations/manifest.rb
325
330
  - lib/zendesk_apps_support/validations/marketplace.rb
326
331
  - lib/zendesk_apps_support/validations/mime.rb