zendesk_apps_support 1.17.0 → 1.17.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/lib/zendesk_apps_support.rb +0 -1
- data/lib/zendesk_apps_support/app_file.rb +5 -5
- data/lib/zendesk_apps_support/app_version.rb +3 -7
- data/lib/zendesk_apps_support/build_translation.rb +1 -4
- data/lib/zendesk_apps_support/engine.rb +0 -2
- data/lib/zendesk_apps_support/i18n.rb +2 -2
- data/lib/zendesk_apps_support/package.rb +32 -33
- data/lib/zendesk_apps_support/sass_functions.rb +1 -3
- data/lib/zendesk_apps_support/stylesheet_compiler.rb +1 -3
- data/lib/zendesk_apps_support/validations/banner.rb +4 -4
- data/lib/zendesk_apps_support/validations/manifest.rb +21 -24
- data/lib/zendesk_apps_support/validations/requirements.rb +6 -8
- data/lib/zendesk_apps_support/validations/source.rb +11 -13
- data/lib/zendesk_apps_support/validations/stylesheets.rb +1 -4
- data/lib/zendesk_apps_support/validations/templates.rb +1 -3
- data/lib/zendesk_apps_support/validations/translations.rb +10 -10
- data/lib/zendesk_apps_support/validations/validation_error.rb +10 -12
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4652177f210c7e96e96dda1dd85b981b2d9017c1
|
4
|
+
data.tar.gz: 707731e9c4eb073339dc46ba1529416b43d63aa0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b31cb09a925f5987c82290c4f4cae89ea09e41ade156db05bd1409d20a4f6e4bb7426ef2cf1710f892579ea5be834b211e863a11a7547d0ba7459518c31c054
|
7
|
+
data.tar.gz: 3b3d587b40cebbcbfba5d704371eb83c8bcd4d3395fe64243ebddf50e3b292d98427ee7fc0b60b91c0d8151ad8d8ee7089cb6b907d6022feb46a39b05075da53
|
data/lib/zendesk_apps_support.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
module ZendeskAppsSupport
|
2
|
-
|
3
2
|
class AppFile
|
4
|
-
|
5
3
|
attr_reader :relative_path
|
6
4
|
attr_reader :absolute_path
|
7
5
|
|
@@ -16,7 +14,11 @@ module ZendeskAppsSupport
|
|
16
14
|
end
|
17
15
|
|
18
16
|
def =~(regex)
|
19
|
-
|
17
|
+
relative_path =~ regex
|
18
|
+
end
|
19
|
+
|
20
|
+
def match(regex)
|
21
|
+
self =~ regex
|
20
22
|
end
|
21
23
|
|
22
24
|
alias_method :to_s, :relative_path
|
@@ -38,7 +40,5 @@ module ZendeskAppsSupport
|
|
38
40
|
def respond_to_missing?(sym, include_private = false)
|
39
41
|
@file.send(:respond_to_missing?, sym, include_private) || super
|
40
42
|
end
|
41
|
-
|
42
43
|
end
|
43
|
-
|
44
44
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'multi_json'
|
2
2
|
|
3
3
|
module ZendeskAppsSupport
|
4
|
-
|
5
4
|
# At any point in time, we support up to three versions:
|
6
5
|
# * deprecated -- we will still serve apps targeting the deprecated version,
|
7
6
|
# but newly created or updated apps CANNOT target it
|
@@ -11,13 +10,12 @@ module ZendeskAppsSupport
|
|
11
10
|
# newly created or updates apps MAY target it, but it
|
12
11
|
# may change without notice
|
13
12
|
class AppVersion
|
14
|
-
|
15
13
|
DEPRECATED = '0.4'.freeze
|
16
14
|
CURRENT = '0.5'.freeze
|
17
15
|
FUTURE = '1.0'.freeze
|
18
16
|
|
19
|
-
TO_BE_SERVED = [
|
20
|
-
VALID_FOR_UPDATE = [
|
17
|
+
TO_BE_SERVED = [DEPRECATED, CURRENT, FUTURE].compact.freeze
|
18
|
+
VALID_FOR_UPDATE = [CURRENT, FUTURE].compact.freeze
|
21
19
|
|
22
20
|
def initialize(version)
|
23
21
|
@version = version.to_s
|
@@ -53,16 +51,14 @@ module ZendeskAppsSupport
|
|
53
51
|
@version
|
54
52
|
end
|
55
53
|
|
56
|
-
def to_json(*
|
54
|
+
def to_json(*)
|
57
55
|
MultiJson.encode(@version)
|
58
56
|
end
|
59
57
|
|
60
58
|
def ==(other)
|
61
59
|
@version == other.to_s
|
62
60
|
end
|
63
|
-
|
64
61
|
end
|
65
62
|
|
66
63
|
AppVersion.freeze
|
67
|
-
|
68
64
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module ZendeskAppsSupport
|
2
2
|
module BuildTranslation
|
3
|
-
|
4
3
|
I18N_TITLE_KEY = 'title'
|
5
4
|
I18N_VALUE_KEY = 'value'
|
6
5
|
I18N_KEYS = [I18N_TITLE_KEY, I18N_VALUE_KEY]
|
@@ -8,7 +7,7 @@ module ZendeskAppsSupport
|
|
8
7
|
def to_flattened_namespaced_hash(hash, target_key = nil, prefix = nil)
|
9
8
|
hash.inject({}) do |result, (key, value)|
|
10
9
|
key = [prefix, key].compact.join('.')
|
11
|
-
if value.
|
10
|
+
if value.is_a?(Hash)
|
12
11
|
if target_key && is_translation_hash?(value)
|
13
12
|
result[key] = value[target_key]
|
14
13
|
else
|
@@ -22,7 +21,6 @@ module ZendeskAppsSupport
|
|
22
21
|
end
|
23
22
|
|
24
23
|
def remove_zendesk_keys(scope, translations = {})
|
25
|
-
|
26
24
|
scope.each_key do |key|
|
27
25
|
context = scope[key]
|
28
26
|
|
@@ -48,6 +46,5 @@ module ZendeskAppsSupport
|
|
48
46
|
def is_translation_hash?(hash)
|
49
47
|
hash.keys.sort == I18N_KEYS
|
50
48
|
end
|
51
|
-
|
52
49
|
end
|
53
50
|
end
|
@@ -20,8 +20,8 @@ module ZendeskAppsSupport
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def locale_files
|
23
|
-
Dir[
|
24
|
-
Dir[
|
23
|
+
Dir[File.expand_path('../../../config/locales/*.yml', __FILE__)] -
|
24
|
+
Dir[File.expand_path('../../../config/locales/*.zendesk.yml', __FILE__)]
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
@@ -6,9 +6,9 @@ module ZendeskAppsSupport
|
|
6
6
|
class Package
|
7
7
|
include ZendeskAppsSupport::BuildTranslation
|
8
8
|
|
9
|
-
DEFAULT_LAYOUT = Erubis::Eruby.new(
|
9
|
+
DEFAULT_LAYOUT = Erubis::Eruby.new(File.read(File.expand_path('../assets/default_template.html.erb', __FILE__)))
|
10
10
|
DEFAULT_SCSS = File.read(File.expand_path('../assets/default_styles.scss', __FILE__))
|
11
|
-
SRC_TEMPLATE = Erubis::Eruby.new(
|
11
|
+
SRC_TEMPLATE = Erubis::Eruby.new(File.read(File.expand_path('../assets/src.js.erb', __FILE__)))
|
12
12
|
|
13
13
|
attr_reader :lib_root, :root, :warnings
|
14
14
|
attr_accessor :requirements_only
|
@@ -22,7 +22,6 @@ module ZendeskAppsSupport
|
|
22
22
|
|
23
23
|
def validate
|
24
24
|
[].tap do |errors|
|
25
|
-
|
26
25
|
errors << Validations::Manifest.call(self)
|
27
26
|
|
28
27
|
if has_manifest?
|
@@ -48,7 +47,7 @@ module ZendeskAppsSupport
|
|
48
47
|
end
|
49
48
|
|
50
49
|
def app_js
|
51
|
-
read_file(
|
50
|
+
read_file('app.js')
|
52
51
|
end
|
53
52
|
|
54
53
|
def commonjs_modules
|
@@ -78,22 +77,22 @@ module ZendeskAppsSupport
|
|
78
77
|
end
|
79
78
|
|
80
79
|
def manifest_json
|
81
|
-
read_json(
|
80
|
+
read_json('manifest.json')
|
82
81
|
end
|
83
82
|
|
84
83
|
def requirements_json
|
85
|
-
read_json(
|
84
|
+
read_json('requirements.json')
|
86
85
|
end
|
87
86
|
|
88
87
|
def translations
|
89
|
-
read_json(
|
88
|
+
read_json('translations/en.json', false)
|
90
89
|
end
|
91
90
|
|
92
91
|
def app_translations
|
93
92
|
remove_zendesk_keys(translations)
|
94
93
|
end
|
95
94
|
|
96
|
-
def readified_js(app_name, app_id, asset_url_prefix, settings={})
|
95
|
+
def readified_js(app_name, app_id, asset_url_prefix, settings = {})
|
97
96
|
manifest = manifest_json
|
98
97
|
source = app_js
|
99
98
|
name = app_name || manifest[:name] || 'Local App'
|
@@ -105,37 +104,37 @@ module ZendeskAppsSupport
|
|
105
104
|
no_template = manifest[:noTemplate]
|
106
105
|
templates = no_template ? {} : compiled_templates(app_id, asset_url_prefix)
|
107
106
|
|
108
|
-
settings[
|
107
|
+
settings['title'] = name
|
109
108
|
|
110
109
|
app_settings = {
|
111
|
-
:
|
112
|
-
:
|
113
|
-
:
|
114
|
-
}.select { |
|
110
|
+
location: location,
|
111
|
+
noTemplate: no_template,
|
112
|
+
singleInstall: single_install
|
113
|
+
}.select { |_k, v| !v.nil? }
|
115
114
|
|
116
115
|
SRC_TEMPLATE.result(
|
117
|
-
:
|
118
|
-
:
|
119
|
-
:
|
120
|
-
:
|
121
|
-
:
|
122
|
-
:
|
123
|
-
:
|
124
|
-
:
|
125
|
-
:
|
126
|
-
:
|
127
|
-
:
|
128
|
-
:
|
116
|
+
name: name,
|
117
|
+
source: source,
|
118
|
+
app_settings: app_settings,
|
119
|
+
asset_url_prefix: asset_url_prefix,
|
120
|
+
app_class_name: app_class_name,
|
121
|
+
author: author,
|
122
|
+
translations: app_translations,
|
123
|
+
framework_version: framework_version,
|
124
|
+
templates: templates,
|
125
|
+
settings: settings,
|
126
|
+
app_id: app_id,
|
127
|
+
modules: commonjs_modules
|
129
128
|
)
|
130
129
|
end
|
131
130
|
|
132
131
|
def customer_css
|
133
132
|
css_file = file_path('app.css')
|
134
|
-
|
133
|
+
File.exist?(css_file) ? File.read(css_file) : ''
|
135
134
|
end
|
136
135
|
|
137
136
|
def has_js?
|
138
|
-
file_exists?(
|
137
|
+
file_exists?('app.js')
|
139
138
|
end
|
140
139
|
|
141
140
|
def has_lib_js?
|
@@ -143,7 +142,7 @@ module ZendeskAppsSupport
|
|
143
142
|
end
|
144
143
|
|
145
144
|
def has_manifest?
|
146
|
-
file_exists?(
|
145
|
+
file_exists?('manifest.json')
|
147
146
|
end
|
148
147
|
|
149
148
|
def has_location?
|
@@ -151,11 +150,11 @@ module ZendeskAppsSupport
|
|
151
150
|
end
|
152
151
|
|
153
152
|
def has_requirements?
|
154
|
-
file_exists?(
|
153
|
+
file_exists?('requirements.json')
|
155
154
|
end
|
156
155
|
|
157
156
|
def has_banner?
|
158
|
-
file_exists?(
|
157
|
+
file_exists?('assets/banner.png')
|
159
158
|
end
|
160
159
|
|
161
160
|
def file_path(path)
|
@@ -168,7 +167,7 @@ module ZendeskAppsSupport
|
|
168
167
|
compiled_css = ZendeskAppsSupport::StylesheetCompiler.new(DEFAULT_SCSS + customer_css, app_id, asset_url_prefix).compile
|
169
168
|
|
170
169
|
templates = begin
|
171
|
-
Dir["#{root
|
170
|
+
Dir["#{root}/templates/*.hdbs"].inject({}) do |h, file|
|
172
171
|
str = File.read(file)
|
173
172
|
str.chomp!
|
174
173
|
h[File.basename(file, File.extname(file))] = str
|
@@ -185,7 +184,7 @@ module ZendeskAppsSupport
|
|
185
184
|
|
186
185
|
def non_tmp_files
|
187
186
|
files = []
|
188
|
-
Dir[
|
187
|
+
Dir[root.join('**/**')].each do |f|
|
189
188
|
next unless File.file?(f)
|
190
189
|
relative_file_name = f.sub(/#{root}\/?/, '')
|
191
190
|
next if relative_file_name =~ /^tmp\//
|
@@ -205,7 +204,7 @@ module ZendeskAppsSupport
|
|
205
204
|
def read_json(path, symbolize_names = true)
|
206
205
|
file = read_file(path)
|
207
206
|
unless file.nil?
|
208
|
-
JSON.parse(read_file(path), :
|
207
|
+
JSON.parse(read_file(path), symbolize_names: symbolize_names)
|
209
208
|
end
|
210
209
|
end
|
211
210
|
end
|
@@ -1,11 +1,10 @@
|
|
1
1
|
require 'sass'
|
2
2
|
|
3
3
|
module Sass::Script::Functions
|
4
|
-
|
5
4
|
module AppAssetUrl
|
6
5
|
def app_asset_url(name)
|
7
6
|
assert_type name, :String
|
8
|
-
result = %
|
7
|
+
result = %{url("#{app_asset_url_helper(name)}")}
|
9
8
|
Sass::Script::String.new(result)
|
10
9
|
end
|
11
10
|
|
@@ -18,5 +17,4 @@ module Sass::Script::Functions
|
|
18
17
|
end
|
19
18
|
|
20
19
|
include AppAssetUrl
|
21
|
-
|
22
20
|
end
|
@@ -2,13 +2,12 @@ require 'sass'
|
|
2
2
|
|
3
3
|
module ZendeskAppsSupport
|
4
4
|
class StylesheetCompiler
|
5
|
-
|
6
5
|
def initialize(source, app_id, url_prefix)
|
7
6
|
@source, @app_id, @url_prefix = source, app_id, url_prefix
|
8
7
|
end
|
9
8
|
|
10
9
|
def compile
|
11
|
-
Sass::Engine.new(wrapped_source, :
|
10
|
+
Sass::Engine.new(wrapped_source, syntax: :scss, app_asset_url_builder: self).render
|
12
11
|
end
|
13
12
|
|
14
13
|
def app_asset_url(name)
|
@@ -20,6 +19,5 @@ module ZendeskAppsSupport
|
|
20
19
|
def wrapped_source
|
21
20
|
".app-#{@app_id} {#{@source}}"
|
22
21
|
end
|
23
|
-
|
24
22
|
end
|
25
23
|
end
|
@@ -17,11 +17,11 @@ module ZendeskAppsSupport
|
|
17
17
|
end
|
18
18
|
|
19
19
|
unless (image.width == BANNER_WIDTH && image.height == BANNER_HEIGHT) ||
|
20
|
-
(image.width == 2*BANNER_WIDTH && image.height == 2*BANNER_HEIGHT)
|
21
|
-
return [ValidationError.new('banner.invalid_size', :
|
22
|
-
:
|
20
|
+
(image.width == 2 * BANNER_WIDTH && image.height == 2 * BANNER_HEIGHT)
|
21
|
+
return [ValidationError.new('banner.invalid_size', required_banner_width: BANNER_WIDTH,
|
22
|
+
required_banner_height: BANNER_HEIGHT)]
|
23
23
|
end
|
24
|
-
rescue
|
24
|
+
rescue
|
25
25
|
return [ValidationError.new('banner.invalid_format')]
|
26
26
|
end
|
27
27
|
end
|
@@ -3,11 +3,10 @@ require 'multi_json'
|
|
3
3
|
module ZendeskAppsSupport
|
4
4
|
module Validations
|
5
5
|
module Manifest
|
6
|
-
|
7
6
|
REQUIRED_MANIFEST_FIELDS = %w( author defaultLocale ).freeze
|
8
7
|
OAUTH_REQUIRED_FIELDS = %w( client_id client_secret authorize_uri access_token_uri ).freeze
|
9
8
|
LOCATIONS_AVAILABLE = %w( top_bar nav_bar ticket_sidebar new_ticket_sidebar user_sidebar ).freeze
|
10
|
-
TYPES_AVAILABLE = %
|
9
|
+
TYPES_AVAILABLE = %w( text password checkbox url number multiline hidden ).freeze
|
11
10
|
|
12
11
|
class <<self
|
13
12
|
def call(package)
|
@@ -42,7 +41,7 @@ module ZendeskAppsSupport
|
|
42
41
|
errors.compact!
|
43
42
|
end
|
44
43
|
rescue MultiJson::DecodeError => e
|
45
|
-
return [ValidationError.new(:manifest_not_json, :
|
44
|
+
return [ValidationError.new(:manifest_not_json, errors: e)]
|
46
45
|
end
|
47
46
|
|
48
47
|
private
|
@@ -63,22 +62,21 @@ module ZendeskAppsSupport
|
|
63
62
|
end
|
64
63
|
|
65
64
|
if missing.any?
|
66
|
-
ValidationError.new('oauth_keys.missing', :
|
65
|
+
ValidationError.new('oauth_keys.missing', missing_keys: missing.join(', '), count: missing.length)
|
67
66
|
end
|
68
|
-
|
69
67
|
end
|
70
68
|
|
71
69
|
def parameters_error(manifest)
|
72
70
|
return unless manifest['parameters']
|
73
71
|
|
74
|
-
unless manifest['parameters'].
|
72
|
+
unless manifest['parameters'].is_a?(Array)
|
75
73
|
return ValidationError.new(:parameters_not_an_array)
|
76
74
|
end
|
77
75
|
|
78
|
-
para_names = manifest['parameters'].collect{|para| para['name']}
|
79
|
-
duplicate_parameters = para_names.select {|name| para_names.count(name) > 1}.uniq
|
76
|
+
para_names = manifest['parameters'].collect { |para| para['name'] }
|
77
|
+
duplicate_parameters = para_names.select { |name| para_names.count(name) > 1 }.uniq
|
80
78
|
unless duplicate_parameters.empty?
|
81
|
-
return ValidationError.new(:duplicate_parameters, :
|
79
|
+
return ValidationError.new(:duplicate_parameters, duplicate_parameters: duplicate_parameters)
|
82
80
|
end
|
83
81
|
end
|
84
82
|
|
@@ -92,11 +90,11 @@ module ZendeskAppsSupport
|
|
92
90
|
|
93
91
|
def default_locale_error(manifest, package)
|
94
92
|
default_locale = manifest['defaultLocale']
|
95
|
-
|
93
|
+
unless default_locale.nil?
|
96
94
|
if default_locale !~ Translations::VALID_LOCALE
|
97
|
-
ValidationError.new(:invalid_default_locale, :
|
95
|
+
ValidationError.new(:invalid_default_locale, defaultLocale: default_locale)
|
98
96
|
elsif package.translation_files.detect { |file| file.relative_path == "translations/#{default_locale}.json" }.nil?
|
99
|
-
ValidationError.new(:missing_translation_file, :
|
97
|
+
ValidationError.new(:missing_translation_file, defaultLocale: default_locale)
|
100
98
|
end
|
101
99
|
end
|
102
100
|
end
|
@@ -108,7 +106,7 @@ module ZendeskAppsSupport
|
|
108
106
|
def invalid_location_error(manifest)
|
109
107
|
invalid_locations = [*manifest['location']] - LOCATIONS_AVAILABLE
|
110
108
|
unless invalid_locations.empty?
|
111
|
-
ValidationError.new(:invalid_location, :
|
109
|
+
ValidationError.new(:invalid_location, invalid_locations: invalid_locations.join(', '), count: invalid_locations.length)
|
112
110
|
end
|
113
111
|
end
|
114
112
|
|
@@ -117,7 +115,7 @@ module ZendeskAppsSupport
|
|
117
115
|
duplicate_locations = *locations.select { |location| locations.count(location) > 1 }.uniq
|
118
116
|
|
119
117
|
unless duplicate_locations.empty?
|
120
|
-
ValidationError.new(:duplicate_location, :
|
118
|
+
ValidationError.new(:duplicate_location, duplicate_locations: duplicate_locations.join(', '), count: duplicate_locations.length)
|
121
119
|
end
|
122
120
|
end
|
123
121
|
|
@@ -134,12 +132,12 @@ module ZendeskAppsSupport
|
|
134
132
|
end
|
135
133
|
|
136
134
|
unless valid_to_serve.include?(target_version)
|
137
|
-
return ValidationError.new(:invalid_version, :
|
135
|
+
return ValidationError.new(:invalid_version, target_version: target_version, available_versions: valid_to_serve.join(', '))
|
138
136
|
end
|
139
137
|
end
|
140
138
|
|
141
139
|
def name_as_parameter_name_error(manifest)
|
142
|
-
if manifest['parameters'].
|
140
|
+
if manifest['parameters'].is_a?(Array)
|
143
141
|
if manifest['parameters'].any? { |p| p['name'] == 'name' }
|
144
142
|
ValidationError.new(:name_as_parameter_name)
|
145
143
|
end
|
@@ -149,35 +147,34 @@ module ZendeskAppsSupport
|
|
149
147
|
def invalid_hidden_parameter_error(manifest)
|
150
148
|
invalid_params = []
|
151
149
|
|
152
|
-
if manifest.
|
150
|
+
if manifest.key?('parameters')
|
153
151
|
invalid_params = manifest['parameters'].select { |p| p['type'] == 'hidden' && p['required'] }.map { |p| p['name'] }
|
154
152
|
end
|
155
153
|
|
156
154
|
if invalid_params.any?
|
157
|
-
ValidationError.new(:invalid_hidden_parameter, :
|
155
|
+
ValidationError.new(:invalid_hidden_parameter, invalid_params: invalid_params.join(', '), count: invalid_params.length)
|
158
156
|
end
|
159
157
|
end
|
160
158
|
|
161
159
|
def invalid_type_error(manifest)
|
162
|
-
return unless manifest['parameters'].
|
160
|
+
return unless manifest['parameters'].is_a?(Array)
|
163
161
|
|
164
162
|
invalid_types = []
|
165
163
|
|
166
|
-
manifest[
|
167
|
-
parameter_type = parameter.fetch(
|
164
|
+
manifest['parameters'].each do |parameter|
|
165
|
+
parameter_type = parameter.fetch('type', '')
|
168
166
|
|
169
167
|
invalid_types << parameter_type unless TYPES_AVAILABLE.include?(parameter_type)
|
170
168
|
end
|
171
169
|
|
172
170
|
if invalid_types.any?
|
173
|
-
ValidationError.new(:invalid_type_parameter, :
|
171
|
+
ValidationError.new(:invalid_type_parameter, invalid_types: invalid_types.join(', '), count: invalid_types.length)
|
174
172
|
end
|
175
173
|
end
|
176
174
|
|
177
175
|
def missing_keys_validation_error(missing_keys)
|
178
|
-
ValidationError.new('manifest_keys.missing', :
|
176
|
+
ValidationError.new('manifest_keys.missing', missing_keys: missing_keys.join(', '), count: missing_keys.length)
|
179
177
|
end
|
180
|
-
|
181
178
|
end
|
182
179
|
end
|
183
180
|
end
|
@@ -4,7 +4,6 @@ require 'json/stream'
|
|
4
4
|
module ZendeskAppsSupport
|
5
5
|
module Validations
|
6
6
|
module Requirements
|
7
|
-
|
8
7
|
MAX_REQUIREMENTS = 5000
|
9
8
|
|
10
9
|
class <<self
|
@@ -16,7 +15,7 @@ module ZendeskAppsSupport
|
|
16
15
|
requirements_stream = requirements_file.read
|
17
16
|
duplicates = non_unique_type_keys(requirements_stream)
|
18
17
|
unless duplicates.empty?
|
19
|
-
return [ValidationError.new(:duplicate_requirements, :
|
18
|
+
return [ValidationError.new(:duplicate_requirements, duplicate_keys: duplicates.join(', '), count: duplicates.length)]
|
20
19
|
end
|
21
20
|
|
22
21
|
requirements = MultiJson.load(requirements_stream)
|
@@ -28,7 +27,7 @@ module ZendeskAppsSupport
|
|
28
27
|
errors.compact!
|
29
28
|
end
|
30
29
|
rescue MultiJson::DecodeError => e
|
31
|
-
return [ValidationError.new(:requirements_not_json, :
|
30
|
+
return [ValidationError.new(:requirements_not_json, errors: e)]
|
32
31
|
end
|
33
32
|
|
34
33
|
private
|
@@ -38,14 +37,14 @@ module ZendeskAppsSupport
|
|
38
37
|
requirements.values.each do |requirement|
|
39
38
|
requirement.each do |identifier, fields|
|
40
39
|
next if fields.include? 'title'
|
41
|
-
errors << ValidationError.new(:missing_required_fields, :
|
40
|
+
errors << ValidationError.new(:missing_required_fields, field: 'title', identifier: identifier)
|
42
41
|
end
|
43
42
|
end
|
44
43
|
|
45
44
|
unless requirements['user_fields'].nil?
|
46
45
|
requirements['user_fields'].each do |identifier, fields|
|
47
46
|
next if fields.include? 'key'
|
48
|
-
errors << ValidationError.new(:missing_required_fields, :
|
47
|
+
errors << ValidationError.new(:missing_required_fields, field: 'key', identifier: identifier)
|
49
48
|
end
|
50
49
|
end
|
51
50
|
end
|
@@ -54,7 +53,7 @@ module ZendeskAppsSupport
|
|
54
53
|
def excessive_requirements(requirements)
|
55
54
|
requirement_count = requirements.values.map(&:values).flatten.size
|
56
55
|
if requirement_count > MAX_REQUIREMENTS
|
57
|
-
ValidationError.new(:excessive_requirements, :
|
56
|
+
ValidationError.new(:excessive_requirements, max: MAX_REQUIREMENTS, count: requirement_count)
|
58
57
|
end
|
59
58
|
end
|
60
59
|
|
@@ -62,7 +61,7 @@ module ZendeskAppsSupport
|
|
62
61
|
invalid_types = requirements.keys - ZendeskAppsSupport::AppRequirement::TYPES
|
63
62
|
|
64
63
|
unless invalid_types.empty?
|
65
|
-
ValidationError.new(:invalid_requirements_types, :
|
64
|
+
ValidationError.new(:invalid_requirements_types, invalid_types: invalid_types.join(', '), count: invalid_types.length)
|
66
65
|
end
|
67
66
|
end
|
68
67
|
|
@@ -78,7 +77,6 @@ module ZendeskAppsSupport
|
|
78
77
|
|
79
78
|
duplicates
|
80
79
|
end
|
81
|
-
|
82
80
|
end
|
83
81
|
end
|
84
82
|
end
|
@@ -3,21 +3,20 @@ require 'jshintrb'
|
|
3
3
|
module ZendeskAppsSupport
|
4
4
|
module Validations
|
5
5
|
module Source
|
6
|
-
|
7
6
|
LINTER_OPTIONS = {
|
8
7
|
# enforcing options:
|
9
|
-
:
|
10
|
-
:
|
8
|
+
noarg: true,
|
9
|
+
undef: true,
|
11
10
|
|
12
11
|
# relaxing options:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
12
|
+
eqnull: true,
|
13
|
+
laxcomma: true,
|
14
|
+
sub: true,
|
16
15
|
|
17
16
|
# predefined globals:
|
18
|
-
:
|
19
|
-
|
20
|
-
|
17
|
+
predef: %w(_ console services helpers alert window document self
|
18
|
+
JSON Base64 clearInterval clearTimeout setInterval setTimeout
|
19
|
+
require module exports top frames parent moment)
|
21
20
|
}.freeze
|
22
21
|
|
23
22
|
class <<self
|
@@ -26,10 +25,10 @@ module ZendeskAppsSupport
|
|
26
25
|
files = package.lib_files << app
|
27
26
|
|
28
27
|
if package.requirements_only
|
29
|
-
return app ? [
|
28
|
+
return app ? [ValidationError.new(:no_app_js_required)] : []
|
30
29
|
end
|
31
30
|
|
32
|
-
return [
|
31
|
+
return [ValidationError.new(:missing_source)] unless app
|
33
32
|
|
34
33
|
jshint_errors(files).flatten!
|
35
34
|
end
|
@@ -38,7 +37,7 @@ module ZendeskAppsSupport
|
|
38
37
|
|
39
38
|
def jshint_error(file)
|
40
39
|
errors = linter.lint(file.read)
|
41
|
-
[
|
40
|
+
[JSHintValidationError.new(file.relative_path, errors)] if errors.any?
|
42
41
|
end
|
43
42
|
|
44
43
|
def jshint_errors(files)
|
@@ -51,7 +50,6 @@ module ZendeskAppsSupport
|
|
51
50
|
def linter
|
52
51
|
Jshintrb::Lint.new(LINTER_OPTIONS)
|
53
52
|
end
|
54
|
-
|
55
53
|
end
|
56
54
|
end
|
57
55
|
end
|
@@ -3,9 +3,7 @@ require 'zendesk_apps_support/stylesheet_compiler'
|
|
3
3
|
module ZendeskAppsSupport
|
4
4
|
module Validations
|
5
5
|
module Stylesheets
|
6
|
-
|
7
6
|
class << self
|
8
|
-
|
9
7
|
def call(package)
|
10
8
|
if css_error = validate_styles(package.customer_css)
|
11
9
|
[css_error]
|
@@ -21,11 +19,10 @@ module ZendeskAppsSupport
|
|
21
19
|
begin
|
22
20
|
compiler.compile
|
23
21
|
rescue Sass::SyntaxError => e
|
24
|
-
return ValidationError.new(:stylesheet_error, :
|
22
|
+
return ValidationError.new(:stylesheet_error, sass_error: e.message)
|
25
23
|
end
|
26
24
|
nil
|
27
25
|
end
|
28
|
-
|
29
26
|
end
|
30
27
|
end
|
31
28
|
end
|
@@ -1,20 +1,18 @@
|
|
1
1
|
module ZendeskAppsSupport
|
2
2
|
module Validations
|
3
3
|
module Templates
|
4
|
-
|
5
4
|
class <<self
|
6
5
|
def call(package)
|
7
6
|
errors = []
|
8
7
|
package.template_files.each do |template|
|
9
8
|
contents = template.read
|
10
9
|
if contents =~ /<\s*style\b/
|
11
|
-
errors << ValidationError.new(:style_in_template, :
|
10
|
+
errors << ValidationError.new(:style_in_template, template: template.relative_path)
|
12
11
|
end
|
13
12
|
end
|
14
13
|
errors
|
15
14
|
end
|
16
15
|
end
|
17
|
-
|
18
16
|
end
|
19
17
|
end
|
20
18
|
end
|
@@ -23,35 +23,35 @@ module ZendeskAppsSupport
|
|
23
23
|
|
24
24
|
def locale_error(file, locale)
|
25
25
|
return nil if VALID_LOCALE =~ locale
|
26
|
-
ValidationError.new('translation.invalid_locale', :
|
26
|
+
ValidationError.new('translation.invalid_locale', file: file.relative_path)
|
27
27
|
end
|
28
28
|
|
29
29
|
def json_error(file)
|
30
30
|
json = MultiJson.load(file.read)
|
31
|
-
if json.
|
32
|
-
if json[
|
33
|
-
json[
|
31
|
+
if json.is_a?(Hash)
|
32
|
+
if json['app'] && json['app']['package']
|
33
|
+
json['app'].delete('package')
|
34
34
|
begin
|
35
35
|
validate_translation_format(json)
|
36
36
|
return
|
37
37
|
rescue TranslationFormatError => e
|
38
|
-
ValidationError.new('translation.invalid_format', :
|
38
|
+
ValidationError.new('translation.invalid_format', field: e.message)
|
39
39
|
end
|
40
40
|
end
|
41
41
|
else
|
42
|
-
ValidationError.new('translation.not_json_object', :
|
42
|
+
ValidationError.new('translation.not_json_object', file: file.relative_path)
|
43
43
|
end
|
44
44
|
rescue MultiJson::DecodeError => e
|
45
|
-
ValidationError.new('translation.not_json', :
|
45
|
+
ValidationError.new('translation.not_json', file: file.relative_path, errors: e)
|
46
46
|
end
|
47
47
|
|
48
48
|
def validate_translation_format(json)
|
49
49
|
json.keys.each do |key|
|
50
|
-
|
50
|
+
fail TranslationFormatError.new("'#{key}': '#{json[key]}'") unless json[key].is_a? Hash
|
51
51
|
|
52
52
|
if json[key].keys.sort == BuildTranslation::I18N_KEYS &&
|
53
|
-
|
54
|
-
|
53
|
+
json[key][BuildTranslation::I18N_TITLE_KEY].class == String &&
|
54
|
+
json[key][BuildTranslation::I18N_VALUE_KEY].class == String
|
55
55
|
next
|
56
56
|
else
|
57
57
|
validate_translation_format(json[key])
|
@@ -2,7 +2,6 @@ require 'multi_json'
|
|
2
2
|
|
3
3
|
module ZendeskAppsSupport
|
4
4
|
module Validations
|
5
|
-
|
6
5
|
class ValidationError
|
7
6
|
KEY_PREFIX = 'txt.apps.admin.error.app_build.'.freeze
|
8
7
|
|
@@ -13,20 +12,19 @@ module ZendeskAppsSupport
|
|
13
12
|
end
|
14
13
|
|
15
14
|
class << self
|
16
|
-
|
17
15
|
# Turn a JSON string into a ValidationError.
|
18
16
|
def from_json(json)
|
19
17
|
hash = MultiJson.decode(json)
|
20
|
-
|
18
|
+
fail DeserializationError.new(json) unless hash.is_a?(Hash)
|
21
19
|
from_hash(hash)
|
22
20
|
rescue MultiJson::DecodeError, NameError
|
23
21
|
raise DeserializationError.new(json)
|
24
22
|
end
|
25
23
|
|
26
24
|
def from_hash(hash)
|
27
|
-
|
25
|
+
fail DeserializationError.new(hash) unless hash['class']
|
28
26
|
klass = constantize(hash['class'])
|
29
|
-
|
27
|
+
fail DeserializationError.new(hash) unless klass <= self
|
30
28
|
klass.vivify(hash)
|
31
29
|
end
|
32
30
|
|
@@ -38,7 +36,7 @@ module ZendeskAppsSupport
|
|
38
36
|
private
|
39
37
|
|
40
38
|
def constantize(klass)
|
41
|
-
klass.to_s.split('::').inject(Object) { |klass, part| klass
|
39
|
+
klass.to_s.split('::').inject(Object) { |klass, part| klass.const_get(part) }
|
42
40
|
end
|
43
41
|
end
|
44
42
|
|
@@ -52,11 +50,11 @@ module ZendeskAppsSupport
|
|
52
50
|
ZendeskAppsSupport::I18n.t("#{KEY_PREFIX}#{key}", data)
|
53
51
|
end
|
54
52
|
|
55
|
-
def to_json(*
|
53
|
+
def to_json(*)
|
56
54
|
MultiJson.encode(as_json)
|
57
55
|
end
|
58
56
|
|
59
|
-
def as_json(*
|
57
|
+
def as_json(*)
|
60
58
|
{
|
61
59
|
'class' => self.class.to_s,
|
62
60
|
'key' => key,
|
@@ -85,13 +83,13 @@ module ZendeskAppsSupport
|
|
85
83
|
errors = jshint_errors.compact.map { |err| "\n L#{err['line']}: #{err['reason']}" }.join('')
|
86
84
|
@filename = filename, @jshint_errors = jshint_errors
|
87
85
|
super(:jshint, {
|
88
|
-
:
|
89
|
-
:
|
90
|
-
:
|
86
|
+
file: filename,
|
87
|
+
errors: errors,
|
88
|
+
count: jshint_errors.length
|
91
89
|
})
|
92
90
|
end
|
93
91
|
|
94
|
-
def as_json(*
|
92
|
+
def as_json(*)
|
95
93
|
{
|
96
94
|
'class' => self.class.to_s,
|
97
95
|
'filename' => filename,
|
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: 1.17.
|
4
|
+
version: 1.17.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: 2015-02-
|
14
|
+
date: 2015-02-16 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: i18n
|
@@ -131,14 +131,14 @@ dependencies:
|
|
131
131
|
requirements:
|
132
132
|
- - "~>"
|
133
133
|
- !ruby/object:Gem::Version
|
134
|
-
version:
|
134
|
+
version: 3.1.0
|
135
135
|
type: :development
|
136
136
|
prerelease: false
|
137
137
|
version_requirements: !ruby/object:Gem::Requirement
|
138
138
|
requirements:
|
139
139
|
- - "~>"
|
140
140
|
- !ruby/object:Gem::Version
|
141
|
-
version:
|
141
|
+
version: 3.1.0
|
142
142
|
- !ruby/object:Gem::Dependency
|
143
143
|
name: bump
|
144
144
|
requirement: !ruby/object:Gem::Requirement
|