zendesk_apps_support 3.3.0 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/config/locales/en.yml +3 -0
- data/config/locales/translations/zendesk_apps_support.yml +4 -0
- data/lib/zendesk_apps_support/app_file.rb +1 -0
- data/lib/zendesk_apps_support/app_requirement.rb +1 -0
- data/lib/zendesk_apps_support/app_version.rb +4 -3
- data/lib/zendesk_apps_support/build_translation.rb +6 -6
- data/lib/zendesk_apps_support/engine.rb +1 -0
- data/lib/zendesk_apps_support/finders.rb +2 -1
- data/lib/zendesk_apps_support/i18n.rb +1 -4
- data/lib/zendesk_apps_support/installation.rb +3 -3
- data/lib/zendesk_apps_support/installed.rb +1 -0
- data/lib/zendesk_apps_support/location.rb +1 -0
- data/lib/zendesk_apps_support/manifest.rb +5 -5
- data/lib/zendesk_apps_support/package.rb +59 -47
- data/lib/zendesk_apps_support/product.rb +1 -0
- data/lib/zendesk_apps_support/sass_functions.rb +1 -0
- data/lib/zendesk_apps_support/stylesheet_compiler.rb +4 -1
- data/lib/zendesk_apps_support/validations/banner.rb +1 -0
- data/lib/zendesk_apps_support/validations/manifest.rb +25 -8
- data/lib/zendesk_apps_support/validations/requirements.rb +6 -5
- data/lib/zendesk_apps_support/validations/source.rb +1 -0
- data/lib/zendesk_apps_support/validations/stylesheets.rb +3 -5
- data/lib/zendesk_apps_support/validations/templates.rb +1 -0
- data/lib/zendesk_apps_support/validations/translations.rb +6 -5
- data/lib/zendesk_apps_support/validations/validation_error.rb +11 -10
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a1d4762759c095666773057863636dd265660b4
|
4
|
+
data.tar.gz: db3af1a717e997011b0923282de990f6c90d1112
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d69521929f65a21a69aba7ab2ec3be6328b2337a8acd191c38d9858609a13ae45825debea2fd404ffbda0400b55625243adf17991883d1660402171b40b8084c
|
7
|
+
data.tar.gz: 4442c141c1a0b58afed6d95c6232d6d3bb026481adf668ea155a905f87714f5da0c984dcab4be0d6ec4f40bdce68e7dac711abad5755aabb8435cfa78237f63e
|
data/config/locales/en.yml
CHANGED
@@ -9,6 +9,9 @@ en:
|
|
9
9
|
jshint:
|
10
10
|
one: 'JSHint error in %{file}: %{errors}'
|
11
11
|
other: 'JSHint errors in %{file}: %{errors}'
|
12
|
+
no_template_deprecated_in_v2: 'noTemplate is deprecated and cannot be
|
13
|
+
used with frameworkVersion 2 or above. Set the autoLoad or autoHide
|
14
|
+
property for each specific location instead. Learn more: %{link}.'
|
12
15
|
no_parameters_required: Parameters can't be defined for marketing-only
|
13
16
|
apps
|
14
17
|
no_location_required: Locations can't be defined when you specify requirements
|
@@ -15,6 +15,10 @@ parts:
|
|
15
15
|
key: "txt.apps.admin.error.app_build.jshint.other"
|
16
16
|
title: "App builder job: JSHint error messages"
|
17
17
|
value: "JSHint errors in %{file}: %{errors}"
|
18
|
+
- translation:
|
19
|
+
key: "txt.apps.admin.error.app_build.no_template_deprecated_in_v2"
|
20
|
+
title: "App builder job: prevent using noTemplate in v2 apps and give advice on how to migrate"
|
21
|
+
value: "noTemplate is deprecated and cannot be used with frameworkVersion 2 or above. Set the autoLoad or autoHide property for each specific location instead. Learn more: %{link}."
|
18
22
|
- translation:
|
19
23
|
key: "txt.apps.admin.error.app_build.no_parameters_required"
|
20
24
|
title: "App builder job: prevent adding parameters while marketing only"
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ZendeskAppsSupport
|
2
3
|
# At any point in time, we support up to three versions:
|
3
4
|
# * deprecated -- we will still serve apps targeting the deprecated version,
|
@@ -8,9 +9,9 @@ module ZendeskAppsSupport
|
|
8
9
|
# newly created or updates apps MAY target it, but it
|
9
10
|
# may change without notice
|
10
11
|
class AppVersion
|
11
|
-
DEPRECATED = '0.5'
|
12
|
-
CURRENT = '1.0'
|
13
|
-
FUTURE = '2.0'
|
12
|
+
DEPRECATED = '0.5'
|
13
|
+
CURRENT = '1.0'
|
14
|
+
FUTURE = '2.0'
|
14
15
|
|
15
16
|
TO_BE_SERVED = [DEPRECATED, CURRENT, FUTURE].compact.freeze
|
16
17
|
VALID_FOR_UPDATE = [CURRENT, FUTURE].compact.freeze
|
@@ -1,14 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ZendeskAppsSupport
|
2
3
|
module BuildTranslation
|
3
4
|
I18N_TITLE_KEY = 'title'
|
4
5
|
I18N_VALUE_KEY = 'value'
|
5
|
-
I18N_KEYS = [I18N_TITLE_KEY, I18N_VALUE_KEY]
|
6
|
+
I18N_KEYS = [I18N_TITLE_KEY, I18N_VALUE_KEY].freeze
|
6
7
|
|
7
8
|
def to_flattened_namespaced_hash(hash, target_key = nil, prefix = nil)
|
8
|
-
hash.
|
9
|
+
hash.each_with_object({}) do |(key, value), result|
|
9
10
|
key = [prefix, key].compact.join('.')
|
10
11
|
if value.is_a?(Hash)
|
11
|
-
if target_key &&
|
12
|
+
if target_key && translation_hash?(value)
|
12
13
|
result[key] = value[target_key]
|
13
14
|
else
|
14
15
|
result.update(to_flattened_namespaced_hash(value, target_key, key))
|
@@ -16,7 +17,6 @@ module ZendeskAppsSupport
|
|
16
17
|
else
|
17
18
|
result[key] = value
|
18
19
|
end
|
19
|
-
result
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -26,7 +26,7 @@ module ZendeskAppsSupport
|
|
26
26
|
|
27
27
|
if context.is_a?(Hash)
|
28
28
|
|
29
|
-
if
|
29
|
+
if translation_hash?(context)
|
30
30
|
translations[key] = context[I18N_VALUE_KEY]
|
31
31
|
else
|
32
32
|
translations[key] ||= {}
|
@@ -43,7 +43,7 @@ module ZendeskAppsSupport
|
|
43
43
|
|
44
44
|
private
|
45
45
|
|
46
|
-
def
|
46
|
+
def translation_hash?(hash)
|
47
47
|
hash.keys.sort == I18N_KEYS
|
48
48
|
end
|
49
49
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ZendeskAppsSupport
|
2
3
|
module Finders
|
3
4
|
class RecordNotFound < StandardError
|
@@ -12,7 +13,7 @@ module ZendeskAppsSupport
|
|
12
13
|
|
13
14
|
def find_by!(arg)
|
14
15
|
found = find_by(arg)
|
15
|
-
|
16
|
+
raise(RecordNotFound, "Unable to find #{name} with #{arg.inspect}") if found.nil?
|
16
17
|
found
|
17
18
|
end
|
18
19
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ZendeskAppsSupport
|
2
3
|
module I18n
|
3
4
|
class << self
|
@@ -5,10 +6,6 @@ module ZendeskAppsSupport
|
|
5
6
|
i18n.t(key, *args)
|
6
7
|
end
|
7
8
|
|
8
|
-
def set_locale(locale)
|
9
|
-
i18n.locale = locale
|
10
|
-
end
|
11
|
-
|
12
9
|
def set_load_path
|
13
10
|
i18n
|
14
11
|
nil
|
@@ -1,6 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ZendeskAppsSupport
|
2
3
|
class Installation
|
3
|
-
|
4
4
|
attr_accessor :id, :app_id, :app_name, :requirements, :settings, :enabled, :updated_at, :created_at
|
5
5
|
|
6
6
|
def initialize(options)
|
@@ -11,8 +11,8 @@ module ZendeskAppsSupport
|
|
11
11
|
|
12
12
|
def to_json
|
13
13
|
hash = {}
|
14
|
-
|
15
|
-
hash[var.to_s.sub('@', '')] =
|
14
|
+
instance_variables.each do |var|
|
15
|
+
hash[var.to_s.sub('@', '')] = instance_variable_get var
|
16
16
|
end
|
17
17
|
hash.to_json
|
18
18
|
end
|
@@ -160,11 +160,11 @@ module ZendeskAppsSupport
|
|
160
160
|
|
161
161
|
def replace_string_uris(product_locations)
|
162
162
|
product_locations.each_with_object({}) do |(k, v), new_locations|
|
163
|
-
if v.is_a? Hash
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
163
|
+
new_locations[k] = if v.is_a? Hash
|
164
|
+
v
|
165
|
+
else
|
166
|
+
{ 'url' => v }
|
167
|
+
end
|
168
168
|
end
|
169
169
|
end
|
170
170
|
|
@@ -15,7 +15,7 @@ module ZendeskAppsSupport
|
|
15
15
|
DEFAULT_SCSS = File.read(File.expand_path('../assets/default_styles.scss', __FILE__))
|
16
16
|
SRC_TEMPLATE = Erubis::Eruby.new(File.read(File.expand_path('../assets/src.js.erb', __FILE__)))
|
17
17
|
|
18
|
-
LOCATIONS_WITH_ICONS = %w(top_bar nav_bar system_top_bar).freeze
|
18
|
+
LOCATIONS_WITH_ICONS = %w(top_bar nav_bar system_top_bar ticket_editor).freeze
|
19
19
|
|
20
20
|
attr_reader :lib_root, :root, :warnings
|
21
21
|
|
@@ -42,9 +42,7 @@ module ZendeskAppsSupport
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
if has_banner?
|
46
|
-
errors << Validations::Banner.call(self)
|
47
|
-
end
|
45
|
+
errors << Validations::Banner.call(self) if has_banner?
|
48
46
|
|
49
47
|
errors.flatten!.compact!
|
50
48
|
end
|
@@ -52,9 +50,7 @@ module ZendeskAppsSupport
|
|
52
50
|
|
53
51
|
def validate!(marketplace: true)
|
54
52
|
errors = validate(marketplace: marketplace)
|
55
|
-
if errors.any?
|
56
|
-
raise errors.first
|
57
|
-
end
|
53
|
+
raise errors.first if errors.any?
|
58
54
|
true
|
59
55
|
end
|
60
56
|
|
@@ -80,27 +76,27 @@ module ZendeskAppsSupport
|
|
80
76
|
files = []
|
81
77
|
Dir[root.join('**/**')].each do |f|
|
82
78
|
next unless File.file?(f)
|
83
|
-
relative_file_name = f.sub(
|
84
|
-
next if relative_file_name =~
|
79
|
+
relative_file_name = f.sub(%r{#{root}/?}, '')
|
80
|
+
next if relative_file_name =~ %r{^tmp/}
|
85
81
|
files << AppFile.new(self, relative_file_name)
|
86
82
|
end
|
87
83
|
files
|
88
84
|
end
|
89
85
|
|
90
86
|
def js_files
|
91
|
-
@js_files ||= files.select { |f| f.to_s == 'app.js' || (
|
87
|
+
@js_files ||= files.select { |f| f.to_s == 'app.js' || (f.to_s.start_with?('lib/') && f.to_s.end_with?('.js')) }
|
92
88
|
end
|
93
89
|
|
94
90
|
def lib_files
|
95
|
-
@lib_files ||= js_files.select { |f| f =~
|
91
|
+
@lib_files ||= js_files.select { |f| f =~ %r{^lib/} }
|
96
92
|
end
|
97
93
|
|
98
94
|
def template_files
|
99
|
-
files.select { |f| f =~
|
95
|
+
files.select { |f| f =~ %r{^templates/.*\.hdbs$} }
|
100
96
|
end
|
101
97
|
|
102
98
|
def translation_files
|
103
|
-
files.select { |f| f =~
|
99
|
+
files.select { |f| f =~ %r{^translations/} }
|
104
100
|
end
|
105
101
|
|
106
102
|
def compile_js(options)
|
@@ -161,7 +157,8 @@ module ZendeskAppsSupport
|
|
161
157
|
deprecate :no_template_locations, 'manifest.no_template_locations', 2016, 9
|
162
158
|
|
163
159
|
def compiled_templates(app_id, asset_url_prefix)
|
164
|
-
|
160
|
+
compiler = ZendeskAppsSupport::StylesheetCompiler.new(DEFAULT_SCSS + app_css, app_id, asset_url_prefix)
|
161
|
+
compiled_css = compiler.compile
|
165
162
|
|
166
163
|
layout = templates['layout'] || DEFAULT_LAYOUT.result
|
167
164
|
|
@@ -185,9 +182,9 @@ module ZendeskAppsSupport
|
|
185
182
|
end
|
186
183
|
|
187
184
|
def app_css
|
188
|
-
|
189
|
-
|
190
|
-
|
185
|
+
return File.read(path_to('app.scss')) if has_file?('app.scss')
|
186
|
+
return File.read(path_to('app.css')) if has_file?('app.css')
|
187
|
+
''
|
191
188
|
end
|
192
189
|
|
193
190
|
def iframe_only?
|
@@ -207,8 +204,8 @@ module ZendeskAppsSupport
|
|
207
204
|
end
|
208
205
|
|
209
206
|
def templates
|
210
|
-
templates_dir =
|
211
|
-
Dir["#{templates_dir}/*.hdbs"].
|
207
|
+
templates_dir = path_to('templates')
|
208
|
+
Dir["#{templates_dir}/*.hdbs"].each_with_object({}) do |file, memo|
|
212
209
|
str = File.read(file)
|
213
210
|
str.chomp!
|
214
211
|
memo[File.basename(file, File.extname(file))] = str
|
@@ -220,30 +217,29 @@ module ZendeskAppsSupport
|
|
220
217
|
return @translations if @is_cached && @translations
|
221
218
|
|
222
219
|
@translations = begin
|
223
|
-
translation_dir =
|
220
|
+
translation_dir = path_to('translations')
|
224
221
|
return {} unless File.directory?(translation_dir)
|
225
222
|
|
226
223
|
locale_path = "#{translation_dir}/#{manifest.default_locale}.json"
|
227
224
|
default_translations = process_translations(locale_path)
|
228
225
|
|
229
|
-
Dir["#{translation_dir}/*.json"].
|
226
|
+
Dir["#{translation_dir}/*.json"].each_with_object({}) do |path, memo|
|
230
227
|
locale = File.basename(path, File.extname(path))
|
231
228
|
|
232
229
|
locale_translations = if locale == manifest.default_locale
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
230
|
+
default_translations
|
231
|
+
else
|
232
|
+
deep_merge_hash(default_translations, process_translations(path))
|
233
|
+
end
|
237
234
|
|
238
235
|
memo[locale] = locale_translations
|
239
|
-
memo
|
240
236
|
end
|
241
237
|
end
|
242
238
|
end
|
243
239
|
|
244
240
|
def process_translations(locale_path)
|
245
241
|
translations = File.exist?(locale_path) ? JSON.parse(File.read(locale_path)) : {}
|
246
|
-
translations['app'].delete('package') if translations.
|
242
|
+
translations['app'].delete('package') if translations.key?('app')
|
247
243
|
remove_zendesk_keys(translations)
|
248
244
|
end
|
249
245
|
|
@@ -272,18 +268,36 @@ module ZendeskAppsSupport
|
|
272
268
|
|
273
269
|
host = location_options.location.product.name
|
274
270
|
location = location_options.location.name
|
275
|
-
location_icons[host][location] =
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
271
|
+
location_icons[host][location] = build_location_icons_hash(location)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
def build_location_icons_hash(location)
|
277
|
+
inactive_png = "icon_#{location}_inactive.png"
|
278
|
+
if has_file?("assets/icon_#{location}.svg")
|
279
|
+
build_svg_icon_hash(location)
|
280
|
+
elsif has_file?("assets/#{inactive_png}")
|
281
|
+
build_png_icons_hash(location)
|
282
|
+
else
|
283
|
+
{}
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
def build_svg_icon_hash(location)
|
288
|
+
cache_busting_param = "?#{Time.now.to_i}" unless @is_cached
|
289
|
+
{ 'svg' => "icon_#{location}.svg#{cache_busting_param}" }
|
290
|
+
end
|
291
|
+
|
292
|
+
def build_png_icons_hash(location)
|
293
|
+
inactive_png = "icon_#{location}_inactive.png"
|
294
|
+
{
|
295
|
+
'inactive' => inactive_png
|
296
|
+
}.tap do |icon_state_hash|
|
297
|
+
%w(active hover).each do |state|
|
298
|
+
specific_png = "icon_#{location}_#{state}.png"
|
299
|
+
selected_png = has_file?("assets/#{specific_png}") ? specific_png : inactive_png
|
300
|
+
icon_state_hash[state] = selected_png
|
287
301
|
end
|
288
302
|
end
|
289
303
|
end
|
@@ -301,11 +315,11 @@ module ZendeskAppsSupport
|
|
301
315
|
def deep_merge_hash(h, another_h)
|
302
316
|
result_h = h.dup
|
303
317
|
another_h.each do |key, value|
|
304
|
-
if h.
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
318
|
+
result_h[key] = if h.key?(key) && h[key].is_a?(Hash) && value.is_a?(Hash)
|
319
|
+
deep_merge_hash(h[key], value)
|
320
|
+
else
|
321
|
+
value
|
322
|
+
end
|
309
323
|
end
|
310
324
|
result_h
|
311
325
|
end
|
@@ -316,9 +330,7 @@ module ZendeskAppsSupport
|
|
316
330
|
|
317
331
|
def read_json(path, parser_opts = {})
|
318
332
|
file = read_file(path)
|
319
|
-
unless file.nil?
|
320
|
-
JSON.parse(read_file(path), parser_opts)
|
321
|
-
end
|
333
|
+
JSON.parse(read_file(path), parser_opts) unless file.nil?
|
322
334
|
end
|
323
335
|
end
|
324
336
|
end
|
@@ -1,10 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'sass'
|
2
3
|
require 'zendesk_apps_support/sass_functions'
|
3
4
|
|
4
5
|
module ZendeskAppsSupport
|
5
6
|
class StylesheetCompiler
|
6
7
|
def initialize(source, app_id, url_prefix)
|
7
|
-
@source
|
8
|
+
@source = source
|
9
|
+
@app_id = app_id
|
10
|
+
@url_prefix = url_prefix
|
8
11
|
end
|
9
12
|
|
10
13
|
def compile
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'uri'
|
2
3
|
|
3
4
|
module ZendeskAppsSupport
|
@@ -6,6 +7,7 @@ module ZendeskAppsSupport
|
|
6
7
|
RUBY_TO_JSON = ZendeskAppsSupport::Manifest::RUBY_TO_JSON
|
7
8
|
REQUIRED_MANIFEST_FIELDS = RUBY_TO_JSON.select { |k| %i(author default_locale).include? k }.freeze
|
8
9
|
OAUTH_REQUIRED_FIELDS = %w(client_id client_secret authorize_uri access_token_uri).freeze
|
10
|
+
PARAMETER_TYPES = ZendeskAppsSupport::Manifest::Parameter::TYPES
|
9
11
|
|
10
12
|
class <<self
|
11
13
|
def call(package)
|
@@ -28,6 +30,8 @@ module ZendeskAppsSupport
|
|
28
30
|
errors << boolean_error(manifest)
|
29
31
|
errors << default_locale_error(manifest, package)
|
30
32
|
|
33
|
+
errors << ban_no_template(manifest) if manifest.iframe_only?
|
34
|
+
|
31
35
|
if manifest.requirements_only? || manifest.marketing_only?
|
32
36
|
errors << ban_location(manifest)
|
33
37
|
errors << ban_framework_version(manifest)
|
@@ -69,6 +73,13 @@ module ZendeskAppsSupport
|
|
69
73
|
end
|
70
74
|
end
|
71
75
|
|
76
|
+
def ban_no_template(manifest)
|
77
|
+
no_template_migration_link = 'https://developer.zendesk.com/apps/docs/apps-v2/manifest#location'
|
78
|
+
if manifest.no_template? || !manifest.no_template_locations.empty?
|
79
|
+
ValidationError.new(:no_template_deprecated_in_v2, link: no_template_migration_link)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
72
83
|
def ban_parameters(manifest)
|
73
84
|
ValidationError.new(:no_parameters_required) unless manifest.parameters.empty?
|
74
85
|
end
|
@@ -131,7 +142,7 @@ module ZendeskAppsSupport
|
|
131
142
|
unless default_locale.nil?
|
132
143
|
if default_locale !~ Translations::VALID_LOCALE
|
133
144
|
ValidationError.new(:invalid_default_locale, default_locale: default_locale)
|
134
|
-
elsif package.translation_files.detect { |
|
145
|
+
elsif package.translation_files.detect { |f| f.relative_path == "translations/#{default_locale}.json" }.nil?
|
135
146
|
ValidationError.new(:missing_translation_file, default_locale: default_locale)
|
136
147
|
end
|
137
148
|
end
|
@@ -155,9 +166,9 @@ module ZendeskAppsSupport
|
|
155
166
|
invalid_locations = package.manifest.unknown_locations(product.name)
|
156
167
|
next if invalid_locations.empty?
|
157
168
|
errors << ValidationError.new(:invalid_location,
|
158
|
-
|
159
|
-
|
160
|
-
|
169
|
+
invalid_locations: invalid_locations.join(', '),
|
170
|
+
host_name: product.name,
|
171
|
+
count: invalid_locations.length)
|
161
172
|
end
|
162
173
|
|
163
174
|
package.manifest.unknown_hosts.each do |unknown_host|
|
@@ -199,7 +210,9 @@ module ZendeskAppsSupport
|
|
199
210
|
end
|
200
211
|
|
201
212
|
unless valid_to_serve.include?(target_version)
|
202
|
-
return ValidationError.new(:invalid_version,
|
213
|
+
return ValidationError.new(:invalid_version,
|
214
|
+
target_version: target_version,
|
215
|
+
available_versions: valid_to_serve.join(', '))
|
203
216
|
end
|
204
217
|
end
|
205
218
|
|
@@ -213,7 +226,9 @@ module ZendeskAppsSupport
|
|
213
226
|
invalid_params = manifest.parameters.select { |p| p.type == 'hidden' && p.required }.map(&:name)
|
214
227
|
|
215
228
|
if invalid_params.any?
|
216
|
-
ValidationError.new(:invalid_hidden_parameter,
|
229
|
+
ValidationError.new(:invalid_hidden_parameter,
|
230
|
+
invalid_params: invalid_params.join(', '),
|
231
|
+
count: invalid_params.length)
|
217
232
|
end
|
218
233
|
end
|
219
234
|
|
@@ -222,7 +237,7 @@ module ZendeskAppsSupport
|
|
222
237
|
manifest.parameters.each do |parameter|
|
223
238
|
parameter_type = parameter.type
|
224
239
|
|
225
|
-
invalid_types << parameter_type unless
|
240
|
+
invalid_types << parameter_type unless PARAMETER_TYPES.include?(parameter_type)
|
226
241
|
end
|
227
242
|
|
228
243
|
if invalid_types.any?
|
@@ -233,7 +248,9 @@ module ZendeskAppsSupport
|
|
233
248
|
end
|
234
249
|
|
235
250
|
def missing_keys_validation_error(missing_keys)
|
236
|
-
ValidationError.new('manifest_keys.missing',
|
251
|
+
ValidationError.new('manifest_keys.missing',
|
252
|
+
missing_keys: missing_keys.join(', '),
|
253
|
+
count: missing_keys.length)
|
237
254
|
end
|
238
255
|
|
239
256
|
def location_framework_mismatch(manifest)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ZendeskAppsSupport
|
2
3
|
module Validations
|
3
4
|
module Requirements
|
@@ -47,10 +48,8 @@ module ZendeskAppsSupport
|
|
47
48
|
end
|
48
49
|
|
49
50
|
def excessive_requirements(requirements)
|
50
|
-
|
51
|
-
if
|
52
|
-
ValidationError.new(:excessive_requirements, max: MAX_REQUIREMENTS, count: requirement_count)
|
53
|
-
end
|
51
|
+
count = requirements.values.map(&:values).flatten.size
|
52
|
+
ValidationError.new(:excessive_requirements, max: MAX_REQUIREMENTS, count: count) if count > MAX_REQUIREMENTS
|
54
53
|
end
|
55
54
|
|
56
55
|
def invalid_user_fields(requirements)
|
@@ -83,7 +82,9 @@ module ZendeskAppsSupport
|
|
83
82
|
invalid_types = requirements.keys - ZendeskAppsSupport::AppRequirement::TYPES
|
84
83
|
|
85
84
|
unless invalid_types.empty?
|
86
|
-
ValidationError.new(:invalid_requirements_types,
|
85
|
+
ValidationError.new(:invalid_requirements_types,
|
86
|
+
invalid_types: invalid_types.join(', '),
|
87
|
+
count: invalid_types.length)
|
87
88
|
end
|
88
89
|
end
|
89
90
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'zendesk_apps_support/stylesheet_compiler'
|
2
3
|
|
3
4
|
module ZendeskAppsSupport
|
@@ -5,11 +6,8 @@ module ZendeskAppsSupport
|
|
5
6
|
module Stylesheets
|
6
7
|
class << self
|
7
8
|
def call(package)
|
8
|
-
|
9
|
-
|
10
|
-
else
|
11
|
-
[]
|
12
|
-
end
|
9
|
+
css_error = validate_styles(package.app_css)
|
10
|
+
css_error ? [css_error] : []
|
13
11
|
end
|
14
12
|
|
15
13
|
private
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'jshintrb'
|
2
3
|
require 'json'
|
3
4
|
|
@@ -12,11 +13,11 @@ module ZendeskAppsSupport
|
|
12
13
|
|
13
14
|
class << self
|
14
15
|
def call(package)
|
15
|
-
package.files.
|
16
|
-
|
16
|
+
package.files.each_with_object([]) do |file, errors|
|
17
|
+
path_match = TRANSLATIONS_PATH.match(file.relative_path)
|
18
|
+
if path_match
|
17
19
|
errors << locale_error(file, path_match[1]) << json_error(file)
|
18
20
|
end
|
19
|
-
errors
|
20
21
|
end.compact
|
21
22
|
end
|
22
23
|
|
@@ -28,7 +29,7 @@ module ZendeskAppsSupport
|
|
28
29
|
end
|
29
30
|
|
30
31
|
def json_error(file)
|
31
|
-
json = JSON.
|
32
|
+
json = JSON.parse(file.read)
|
32
33
|
if json.is_a?(Hash)
|
33
34
|
if json['app'] && json['app']['package']
|
34
35
|
json['app'].delete('package')
|
@@ -48,7 +49,7 @@ module ZendeskAppsSupport
|
|
48
49
|
|
49
50
|
def validate_translation_format(json)
|
50
51
|
json.keys.each do |key|
|
51
|
-
|
52
|
+
raise TranslationFormatError, "'#{key}': '#{json[key]}'" unless json[key].is_a? Hash
|
52
53
|
|
53
54
|
if json[key].keys.sort == BuildTranslation::I18N_KEYS &&
|
54
55
|
json[key][BuildTranslation::I18N_TITLE_KEY].class == String &&
|
@@ -1,9 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'json'
|
2
3
|
|
3
4
|
module ZendeskAppsSupport
|
4
5
|
module Validations
|
5
6
|
class ValidationError < StandardError
|
6
|
-
KEY_PREFIX = 'txt.apps.admin.error.app_build.'
|
7
|
+
KEY_PREFIX = 'txt.apps.admin.error.app_build.'
|
7
8
|
|
8
9
|
class DeserializationError < StandardError
|
9
10
|
def initialize(serialized)
|
@@ -14,17 +15,17 @@ module ZendeskAppsSupport
|
|
14
15
|
class << self
|
15
16
|
# Turn a JSON string into a ValidationError.
|
16
17
|
def from_json(json)
|
17
|
-
hash = JSON.
|
18
|
-
|
18
|
+
hash = JSON.parse(json)
|
19
|
+
raise DeserializationError, json unless hash.is_a?(Hash)
|
19
20
|
from_hash(hash)
|
20
21
|
rescue JSON::ParserError, NameError
|
21
|
-
raise DeserializationError
|
22
|
+
raise DeserializationError, json
|
22
23
|
end
|
23
24
|
|
24
25
|
def from_hash(hash)
|
25
|
-
|
26
|
+
raise DeserializationError, hash unless hash['class']
|
26
27
|
klass = constantize(hash['class'])
|
27
|
-
|
28
|
+
raise DeserializationError, hash unless klass <= self
|
28
29
|
klass.vivify(hash)
|
29
30
|
end
|
30
31
|
|
@@ -36,14 +37,15 @@ module ZendeskAppsSupport
|
|
36
37
|
private
|
37
38
|
|
38
39
|
def constantize(klass)
|
39
|
-
klass.to_s.split('::').inject(Object) { |
|
40
|
+
klass.to_s.split('::').inject(Object) { |superclass, part| superclass.const_get(part) }
|
40
41
|
end
|
41
42
|
end
|
42
43
|
|
43
44
|
attr_reader :key, :data
|
44
45
|
|
45
46
|
def initialize(key, data = nil)
|
46
|
-
@key
|
47
|
+
@key = key
|
48
|
+
@data = symbolize_keys(data || {})
|
47
49
|
end
|
48
50
|
|
49
51
|
def to_s
|
@@ -65,9 +67,8 @@ module ZendeskAppsSupport
|
|
65
67
|
private
|
66
68
|
|
67
69
|
def symbolize_keys(hash)
|
68
|
-
hash.
|
70
|
+
hash.each_with_object({}) do |(key, value), result|
|
69
71
|
result[key.to_sym] = value
|
70
|
-
result
|
71
72
|
end
|
72
73
|
end
|
73
74
|
end
|
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: 3.3.
|
4
|
+
version: 3.3.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: 2016-12-
|
14
|
+
date: 2016-12-13 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: i18n
|
@@ -216,7 +216,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
216
216
|
version: 1.3.6
|
217
217
|
requirements: []
|
218
218
|
rubyforge_project:
|
219
|
-
rubygems_version: 2.
|
219
|
+
rubygems_version: 2.5.1
|
220
220
|
signing_key:
|
221
221
|
specification_version: 4
|
222
222
|
summary: Support to help you develop Zendesk Apps.
|