zendesk_apps_support 3.3.0 → 3.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|