solara 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/solara/lib/core/.DS_Store +0 -0
  3. data/solara/lib/core/aliases/alias_generator.rb +1 -0
  4. data/solara/lib/core/aliases/alias_generator_manager.rb +2 -1
  5. data/solara/lib/core/aliases/solara_terminal_setup.rb +1 -1
  6. data/solara/lib/core/brands/brand_font_switcher.rb +154 -0
  7. data/solara/lib/core/brands/brand_onboarder.rb +8 -6
  8. data/solara/lib/core/brands/brand_switcher.rb +232 -166
  9. data/solara/lib/core/brands/brands_manager.rb +15 -39
  10. data/solara/lib/core/dashboard/brand/BrandDetail.js +19 -0
  11. data/solara/lib/core/dashboard/brand/BrandDetailController.js +50 -8
  12. data/solara/lib/core/dashboard/brand/BrandDetailModel.js +9 -30
  13. data/solara/lib/core/dashboard/brand/BrandDetailView.js +49 -3
  14. data/solara/lib/core/dashboard/brand/InfoPlistStringCatalogManager.js +19 -0
  15. data/solara/lib/core/dashboard/brand/brand.html +209 -62
  16. data/solara/lib/core/dashboard/brand/source/BrandLocalSource.js +1 -1
  17. data/solara/lib/core/dashboard/brand/source/BrandRemoteSource.js +38 -53
  18. data/solara/lib/core/dashboard/brands/BrandsController.js +6 -5
  19. data/solara/lib/core/dashboard/brands/BrandsModel.js +2 -2
  20. data/solara/lib/core/dashboard/brands/BrandsView.js +2 -2
  21. data/solara/lib/core/dashboard/brands/brands.html +3 -1
  22. data/solara/lib/core/dashboard/component/AliasesBottomSheet.js +7 -5
  23. data/solara/lib/core/dashboard/dashboard_manager.rb +2 -0
  24. data/solara/lib/core/dashboard/dashboard_server.rb +1 -3
  25. data/solara/lib/core/dashboard/handler/brand_alisases_handler.rb +4 -11
  26. data/solara/lib/core/dashboard/handler/brand_configurations_manager.rb +11 -11
  27. data/solara/lib/core/dashboard/handler/{brand_configurations_handler.rb → brand_details_handler.rb} +4 -4
  28. data/solara/lib/core/dashboard/handler/brands_handler.rb +1 -1
  29. data/solara/lib/core/dashboard/handler/edit_section_handler.rb +8 -8
  30. data/solara/lib/core/doctor/brand_doctor.rb +31 -31
  31. data/solara/lib/core/doctor/doctor_manager.rb +0 -1
  32. data/solara/lib/core/doctor/project_doctor.rb +0 -1
  33. data/solara/lib/core/doctor/schema/platform/android/android_config.json +0 -4
  34. data/solara/lib/core/doctor/schema/platform/ios/InfoPlist.xcstrings +15 -0
  35. data/solara/lib/core/doctor/schema/platform/ios/ios_config.json +0 -5
  36. data/solara/lib/core/doctor/schema/platform/shared/brand_config.json +9 -0
  37. data/solara/lib/core/doctor/schema/platform/shared/theme.json +94 -9
  38. data/solara/lib/core/doctor/validator/brand_settings_validator.rb +6 -0
  39. data/solara/lib/core/doctor/validator/brand_settings_validator_manager.rb +9 -21
  40. data/solara/lib/core/doctor/validator/template/android_template_validation_config.yml +22 -4
  41. data/solara/lib/core/doctor/validator/template/flutter_template_validation_config.yml +22 -6
  42. data/solara/lib/core/doctor/validator/template/ios_template_validation_config.yml +22 -4
  43. data/solara/lib/core/scripts/brand_config_generator.rb +1 -0
  44. data/solara/lib/core/scripts/brand_config_manager.rb +2 -4
  45. data/solara/lib/core/scripts/brand_exporter.rb +1 -1
  46. data/solara/lib/core/scripts/brand_importer.rb +2 -3
  47. data/solara/lib/core/scripts/brand_offboarder.rb +5 -0
  48. data/solara/lib/core/scripts/brand_resources_manager.rb +127 -54
  49. data/solara/lib/core/scripts/directory_creator.rb +2 -2
  50. data/solara/lib/core/scripts/file_manager.rb +53 -19
  51. data/solara/lib/core/scripts/file_path.rb +175 -30
  52. data/solara/lib/core/scripts/folder_copier.rb +3 -7
  53. data/solara/lib/core/scripts/gitignore_manager.rb +21 -10
  54. data/solara/lib/core/scripts/interactive_file_system_validator.rb +8 -2
  55. data/solara/lib/core/scripts/platform/android/android_manifest_switcher.rb +3 -3
  56. data/solara/lib/core/scripts/platform/android/android_strings_switcher.rb +26 -24
  57. data/solara/lib/core/scripts/platform/android/gradle_switcher.rb +7 -6
  58. data/solara/lib/core/scripts/platform/ios/infoplist_string_catalog_manager.rb +123 -0
  59. data/solara/lib/core/scripts/platform/ios/infoplist_switcher.rb +59 -0
  60. data/solara/lib/core/scripts/platform/ios/ios_plist_manager.rb +11 -20
  61. data/solara/lib/core/scripts/platform/ios/plist_font_manager.rb +33 -0
  62. data/solara/lib/core/scripts/platform/ios/xcconfig_generator.rb +15 -3
  63. data/solara/lib/core/scripts/platform/ios/xcode_asset_manager.rb +2 -3
  64. data/solara/lib/core/scripts/platform/ios/xcode_project_manager.rb +80 -1
  65. data/solara/lib/core/scripts/platform/ios/xcode_project_switcher.rb +15 -34
  66. data/solara/lib/core/scripts/solara_logger.rb +10 -0
  67. data/solara/lib/core/scripts/solara_settings_manager.rb +26 -1
  68. data/solara/lib/core/scripts/strings_xml_manager.rb +17 -2
  69. data/solara/lib/core/scripts/theme_generator.rb +133 -130
  70. data/solara/lib/core/scripts/yaml_manager.rb +23 -0
  71. data/solara/lib/core/solara_configurator.rb +1 -1
  72. data/solara/lib/core/template/brands/android/android_config.json +0 -1
  73. data/solara/lib/core/template/brands/android/res/values/strings.xml +4 -0
  74. data/solara/lib/core/template/brands/ios/InfoPlist.xcstrings +30 -0
  75. data/solara/lib/core/template/brands/ios/ios_config.json +1 -2
  76. data/solara/lib/core/template/brands/shared/brand_config.json +1 -0
  77. data/solara/lib/core/template/brands/shared/theme.json +3 -3
  78. data/solara/lib/core/template/config/android_template_config.json +11 -1
  79. data/solara/lib/core/template/config/flutter_template_config.json +12 -2
  80. data/solara/lib/core/template/config/ios_template_config.json +11 -1
  81. data/solara/lib/core/template/project_template_generator.rb +8 -3
  82. data/solara/lib/solara/version.rb +1 -1
  83. data/solara/lib/solara.rb +8 -4
  84. data/solara/lib/solara_initializer.rb +5 -2
  85. data/solara/lib/solara_manager.rb +1 -1
  86. metadata +62 -43
  87. data/solara/lib/core/dashboard/handler/brand_section_handler.rb +0 -20
  88. data/solara/lib/core/doctor/validator/directory_structure_validator.rb +0 -38
  89. data/solara/lib/core/doctor/validator/file_structure_validator.rb +0 -37
  90. data/solara/lib/core/scripts/platform/ios/ios_file_path_manager.rb +0 -109
  91. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/.DS_Store +0 -0
  92. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/100.png +0 -0
  93. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/102.png +0 -0
  94. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/1024.png +0 -0
  95. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/114.png +0 -0
  96. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/120.png +0 -0
  97. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/128.png +0 -0
  98. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/144.png +0 -0
  99. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/152.png +0 -0
  100. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/16.png +0 -0
  101. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/167.png +0 -0
  102. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/172.png +0 -0
  103. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/180.png +0 -0
  104. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/196.png +0 -0
  105. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/20.png +0 -0
  106. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/216.png +0 -0
  107. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/256.png +0 -0
  108. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/29.png +0 -0
  109. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/32.png +0 -0
  110. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/40.png +0 -0
  111. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/48.png +0 -0
  112. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/50.png +0 -0
  113. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/512.png +0 -0
  114. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/55.png +0 -0
  115. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/57.png +0 -0
  116. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/58.png +0 -0
  117. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/60.png +0 -0
  118. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/64.png +0 -0
  119. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/66.png +0 -0
  120. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/72.png +0 -0
  121. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/76.png +0 -0
  122. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/80.png +0 -0
  123. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/87.png +0 -0
  124. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/88.png +0 -0
  125. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/92.png +0 -0
  126. /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/Contents.json +0 -0
@@ -90,26 +90,28 @@ class AliasesBottomSheet extends HTMLElement {
90
90
  this.overlay.onclick = () => this.hide();
91
91
  }
92
92
 
93
- show(aliases, brand) {
93
+ show(aliases, brandKey) {
94
94
  const commonAliasesList = this.shadowRoot.getElementById('commonAliasesList');
95
95
  const brandAliasesList = this.shadowRoot.getElementById('brandAliasesList');
96
96
 
97
97
  commonAliasesList.innerHTML = '';
98
98
  brandAliasesList.innerHTML = '';
99
99
 
100
+ const pattern = /alias|='[^']*'/g;
101
+
100
102
  aliases.aliases.common_aliases.forEach(alias => {
101
103
  const li = document.createElement('li');
102
- li.textContent = alias;
104
+ li.textContent = alias.replace(pattern, '').trim();
103
105
  commonAliasesList.appendChild(li);
104
106
  });
105
107
 
106
- const brandAliases = aliases.aliases.brand_aliases[brand.key] || [];
108
+ const brandAliases = aliases.aliases.brand_aliases[brandKey] || [];
109
+
107
110
  brandAliases.forEach(alias => {
108
111
  const li = document.createElement('li');
109
- li.textContent = alias;
112
+ li.textContent = alias.replace(pattern, '').trim();
110
113
  brandAliasesList.appendChild(li);
111
114
  });
112
-
113
115
  this.aliasesBottomSheet.style.display = 'block';
114
116
  this.overlay.style.display = 'block';
115
117
 
@@ -1,6 +1,8 @@
1
1
  class DashboardManager
2
2
 
3
3
  def start(brand_key = nil, port = 8000)
4
+ return if SolaraEnvironment.is_test
5
+
4
6
  Solara.logger.header("Solara Dashboard #{brand_key.nil? || brand_key.empty? ? "" : "for #{brand_key}"}")
5
7
  if brand_key.nil? || brand_key.empty?
6
8
  open("brands/brands.html?source=local", port)
@@ -1,5 +1,4 @@
1
1
  Dir[File.expand_path('handler/*.rb', __dir__)].each { |file| require_relative file }
2
- Dir[File.expand_path('../.solara/core/brands/*.rb')].each { |file| require_relative file }
3
2
  Dir[File.expand_path('platform/android/*.rb', __dir__)].each { |file| require_relative file }
4
3
  Dir[File.expand_path('scripts/*.rb', __dir__)].each { |file| require_relative file }
5
4
 
@@ -65,10 +64,9 @@ class DashboardServer
65
64
  return if @router.nil?
66
65
 
67
66
  @router.register_handler(RedirectHandler)
68
- @router.register_handler(BrandSectionHandler)
69
67
  @router.register_handler(SwitchToBrandHandler)
70
68
  @router.register_handler(CurrentBrandHandler)
71
- @router.register_handler(BrandConfigurationsHandler)
69
+ @router.register_handler(BrandDetailsHandler)
72
70
  @router.register_handler(BrandsHandler)
73
71
  @router.register_handler(EditSectionHandler)
74
72
  @router.register_handler(OnboardBrandHandler)
@@ -3,17 +3,10 @@ class BrandAliasesHandler < BaseHandler
3
3
  @server.mount_proc('/brand/aliases') do |req, res|
4
4
  if req.request_method == 'GET'
5
5
  begin
6
- query = CGI.parse(req.query_string)
7
- brand_key = query['brand_key']&.first
6
+ aliases = get_brand_aliases
7
+ res.status = 200
8
+ res.body = JSON.generate({ success: true, aliases: aliases })
8
9
 
9
- if brand_key
10
- aliases = get_brand_aliases(brand_key)
11
- res.status = 200
12
- res.body = JSON.generate({ success: true, aliases: aliases })
13
- else
14
- res.status = 400
15
- res.body = JSON.generate({ success: false, error: 'Missing brand_key parameter' })
16
- end
17
10
  rescue StandardError => e
18
11
  handle_error(res, e, "Error fetching brand aliases")
19
12
  end
@@ -24,7 +17,7 @@ class BrandAliasesHandler < BaseHandler
24
17
  end
25
18
  end
26
19
 
27
- def get_brand_aliases(brand_key)
20
+ def get_brand_aliases
28
21
  AliasGeneratorManager.aliases_json
29
22
  rescue StandardError => e
30
23
  Solara.logger.failure("Error getting brand aliases: #{e.message}")
@@ -11,37 +11,37 @@ class BrandConfigurationsManager
11
11
  def templates
12
12
  [
13
13
  {
14
- key: 'theme',
15
- name: 'Theme Configuration',
16
- input_type: 'color',
17
- path: FilePath.brand_theme(@brand_key)
18
- },
19
- {
20
- key: 'brand_config',
14
+ key: 'brand_config.json',
21
15
  name: 'Brand Configuration',
22
16
  input_type: 'text',
23
17
  path: FilePath.brand_config(@brand_key)
24
18
  },
25
19
  {
26
- key: 'android_config',
20
+ key: 'theme.json',
21
+ name: 'Theme Configuration',
22
+ input_type: 'color',
23
+ path: FilePath.brand_theme(@brand_key)
24
+ },
25
+ {
26
+ key: 'android_config.json',
27
27
  name: 'Android Platform Configuration',
28
28
  input_type: 'text',
29
29
  path: FilePath.android_brand_config(@brand_key)
30
30
  },
31
31
  {
32
- key: 'android_signing',
32
+ key: 'android_signing.json',
33
33
  name: 'Android Signing',
34
34
  input_type: 'text',
35
35
  path: FilePath.brand_signing(@brand_key, Platform::Android)
36
36
  },
37
37
  {
38
- key: 'ios_config',
38
+ key: 'ios_config.json',
39
39
  name: 'iOS Platform Configuration',
40
40
  input_type: 'text',
41
41
  path: FilePath.ios_config(@brand_key)
42
42
  },
43
43
  {
44
- key: 'ios_signing',
44
+ key: 'ios_signing.json',
45
45
  name: 'iOS Signing',
46
46
  input_type: 'text',
47
47
  path: FilePath.brand_signing(@brand_key, Platform::IOS)
@@ -1,15 +1,15 @@
1
- class BrandConfigurationsHandler < BaseHandler
1
+ class BrandDetailsHandler < BaseHandler
2
2
  def mount
3
- @server.mount_proc('/configurations') do |req, res|
3
+ @server.mount_proc('/brand/details') do |req, res|
4
4
  begin
5
5
  query = CGI.parse(req.query_string)
6
6
  brand_key = query['brand_key']&.first
7
7
 
8
8
  response_data = BrandsManager.instance.brand_with_configurations(brand_key)
9
- res.body = JSON.generate({ success: true, message: "Configurations response", result: response_data })
9
+ res.body = JSON.generate({ success: true, message: "Brand details response", result: response_data })
10
10
  res['Content-Type'] = 'application/json'
11
11
  rescue StandardError => e
12
- handle_error(res, e, "Error in brand configurations handler")
12
+ handle_error(res, e, "Error in brand details handler")
13
13
  end
14
14
  end
15
15
  end
@@ -1,6 +1,6 @@
1
1
  class BrandsHandler < BaseHandler
2
2
  def mount
3
- @server.mount_proc('/brands.json') do |req, res|
3
+ @server.mount_proc('/brands/all') do |req, res|
4
4
  begin
5
5
  brands_list = BrandsManager.instance.brands_list
6
6
  json = JSON.generate(brands_list)
@@ -31,8 +31,13 @@ class EditSectionHandler < BaseHandler
31
31
  template = BrandConfigurationsManager.new(brand_key).template_with_key(key)
32
32
 
33
33
  path = template[:path]
34
+
34
35
  if File.exist?(path)
35
- File.write(path, JSON.pretty_generate(data))
36
+ if key === 'InfoPlist.xcstrings'
37
+ InfoPListStringCatalogManager.new(FilePath.brand_infoplist_string_catalog(brand_key)).update(data)
38
+ else
39
+ File.write(path, JSON.pretty_generate(data))
40
+ end
36
41
  Solara.logger.debug("Updated Config for #{path}: #{data}")
37
42
  else
38
43
  raise "Config file not found: #{path}"
@@ -42,14 +47,9 @@ class EditSectionHandler < BaseHandler
42
47
  raise
43
48
  end
44
49
 
45
- def update_theme(path, data)
46
- json = JSON.parse(File.read(path))
47
- json['colors'] = data
48
- File.write(path, JSON.pretty_generate(json))
49
- end
50
-
51
50
  def set_current_brand_content_changed(brand_key, changed)
52
51
  BrandsManager.instance.set_current_brand_content_changed(brand_key, changed)
53
52
  end
54
53
 
55
- end
54
+ end
55
+
@@ -1,35 +1,6 @@
1
1
  Dir.glob("#{__dir__}/*.rb").each { |file| require file }
2
- Dir.glob("#{__dir__}/../../.solara/core/brands/*.rb").each { |file| require file }
3
2
  Dir.glob("#{__dir__}/validator/template/*.rb").each { |file| require file }
4
3
 
5
- class Issue < StandardError
6
- ERROR = 'ERROR'
7
- WARNING = 'WARNING'
8
-
9
- attr_reader :type, :error
10
-
11
- def initialize(type, error)
12
- @type = type
13
- @error = error
14
- end
15
-
16
- def to_s
17
- "#{@type}: #{@error}"
18
- end
19
-
20
- def <=>(other)
21
- [type, error] <=> [other.type, other.error]
22
- end
23
-
24
- def self.error(error)
25
- Issue.new(ERROR, error)
26
- end
27
-
28
- def self.warning(error)
29
- Issue.new(WARNING, error)
30
- end
31
- end
32
-
33
4
  class BrandDoctor
34
5
  def initialize
35
6
  end
@@ -37,6 +8,7 @@ class BrandDoctor
37
8
  def visit(brand_keys = [], print_logs: true)
38
9
  keys = brand_keys.empty? ? BrandsManager.instance.brands_list.map { |brand| brand['key'] } : brand_keys
39
10
  issues = []
11
+ has_template_errors = false
40
12
 
41
13
  keys.each do |brand_key|
42
14
  validator = TemplateValidator.new(FilePath.brand(brand_key), FilePath.template_validation_config)
@@ -45,15 +17,16 @@ class BrandDoctor
45
17
  errors.each { |error|
46
18
  issues << Issue.error(error)
47
19
  }
20
+ has_template_errors = true unless issues.select { |issue| issue.type == Issue::ERROR }.empty?
48
21
  end
49
22
 
50
23
  # Validate settings only if all validations so far are passed to avoid files issues
51
- if issues.select { |issue| issue.type == Issue::ERROR }.empty?
24
+ unless has_template_errors
52
25
  issues += BrandSettingsValidatorManager.new.validate
53
26
  end
54
27
 
55
28
  if print_logs && !issues.empty?
56
- Solara.logger.title("Healt Check Result")
29
+ Solara.logger.title("Health Check Result")
57
30
 
58
31
  issues.sort!.each { |issue|
59
32
  case issue.type
@@ -92,3 +65,30 @@ class BrandDoctor
92
65
  end
93
66
  end
94
67
 
68
+ class Issue < StandardError
69
+ ERROR = 'ERROR'
70
+ WARNING = 'WARNING'
71
+
72
+ attr_reader :type, :error
73
+
74
+ def initialize(type, error)
75
+ @type = type
76
+ @error = error
77
+ end
78
+
79
+ def to_s
80
+ "#{@type}: #{@error}"
81
+ end
82
+
83
+ def <=>(other)
84
+ [type, error] <=> [other.type, other.error]
85
+ end
86
+
87
+ def self.error(error)
88
+ Issue.new(ERROR, error)
89
+ end
90
+
91
+ def self.warning(error)
92
+ Issue.new(WARNING, error)
93
+ end
94
+ end
@@ -1,7 +1,6 @@
1
1
  Dir.glob("#{__dir__}/*.rb").each { |file| require file }
2
2
  Dir.glob("#{__dir__}/validator/*.rb").each { |file| require file }
3
3
  Dir.glob("#{__dir__}/brand/*.rb").each { |file| require file }
4
- Dir.glob("#{__dir__}/../../.solara/core/brands/*.rb").each { |file| require file }
5
4
 
6
5
  class DoctorManager
7
6
  def initialize
@@ -1,5 +1,4 @@
1
1
  Dir.glob("#{__dir__}/*.rb").each { |file| require file }
2
- Dir.glob("#{__dir__}/../../.solara/core/brands/*.rb").each { |file| require file }
3
2
 
4
3
  class ProjectDoctor
5
4
  def visit
@@ -1,15 +1,11 @@
1
1
  {
2
2
  "type": "object",
3
3
  "required": [
4
- "brandName",
5
4
  "applicationId",
6
5
  "versionName",
7
6
  "versionCode"
8
7
  ],
9
8
  "properties": {
10
- "brandName": {
11
- "type": "string"
12
- },
13
9
  "applicationId": {
14
10
  "type": "string"
15
11
  },
@@ -0,0 +1,15 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "sourceLanguage": {
5
+ "type": "string"
6
+ },
7
+ "strings": {
8
+ "type": "object"
9
+ },
10
+ "version": {
11
+ "type": "string"
12
+ }
13
+ },
14
+ "required": ["sourceLanguage", "strings", "version"]
15
+ }
@@ -1,10 +1,6 @@
1
1
  {
2
2
  "type": "object",
3
3
  "properties": {
4
- "PRODUCT_NAME": {
5
- "type": "string",
6
- "description": "The name of the product."
7
- },
8
4
  "PRODUCT_BUNDLE_IDENTIFIER": {
9
5
  "type": "string",
10
6
  "description": "The bundle identifier of the product."
@@ -19,7 +15,6 @@
19
15
  }
20
16
  },
21
17
  "required": [
22
- "PRODUCT_NAME",
23
18
  "PRODUCT_BUNDLE_IDENTIFIER",
24
19
  "MARKETING_VERSION",
25
20
  "BUNDLE_VERSION"
@@ -0,0 +1,9 @@
1
+ {
2
+ "type": "object",
3
+ "brandName": {
4
+ "type": "string"
5
+ },
6
+ "required": [
7
+ "brandName"
8
+ ]
9
+ }
@@ -3,8 +3,7 @@
3
3
  "properties": {
4
4
  "colors": {
5
5
  "type": "object",
6
- "properties": {
7
- },
6
+ "properties": {},
8
7
  "required": []
9
8
  },
10
9
  "typography": {
@@ -13,36 +12,122 @@
13
12
  "fontFamily": {
14
13
  "type": "object",
15
14
  "properties": {
15
+ "regular": {
16
+ "type": "string"
17
+ },
18
+ "medium": {
19
+ "type": "string"
20
+ },
21
+ "bold": {
22
+ "type": "string"
23
+ }
16
24
  },
17
- "required": []
25
+ "required": [
26
+ "regular",
27
+ "medium",
28
+ "bold"
29
+ ]
18
30
  },
19
31
  "fontSize": {
20
32
  "type": "object",
21
33
  "properties": {
34
+ "small": {
35
+ "type": "number"
36
+ },
37
+ "medium": {
38
+ "type": "number"
39
+ },
40
+ "large": {
41
+ "type": "number"
42
+ },
43
+ "extraLarge": {
44
+ "type": "number"
45
+ }
22
46
  },
23
- "required": []
47
+ "required": [
48
+ "small",
49
+ "medium",
50
+ "large",
51
+ "extraLarge"
52
+ ]
24
53
  }
25
54
  },
26
- "required": ["fontFamily", "fontSize"]
55
+ "required": [
56
+ "fontFamily",
57
+ "fontSize"
58
+ ]
27
59
  },
28
60
  "spacing": {
29
61
  "type": "object",
30
62
  "properties": {
63
+ "small": {
64
+ "type": "number"
65
+ },
66
+ "medium": {
67
+ "type": "number"
68
+ },
69
+ "large": {
70
+ "type": "number"
71
+ },
72
+ "extraLarge": {
73
+ "type": "number"
74
+ }
31
75
  },
32
- "required": []
76
+ "required": [
77
+ "small",
78
+ "medium",
79
+ "large",
80
+ "extraLarge"
81
+ ]
33
82
  },
34
83
  "borderRadius": {
35
84
  "type": "object",
36
85
  "properties": {
86
+ "small": {
87
+ "type": "number"
88
+ },
89
+ "medium": {
90
+ "type": "number"
91
+ },
92
+ "large": {
93
+ "type": "number"
94
+ }
37
95
  },
38
- "required": []
96
+ "required": [
97
+ "small",
98
+ "medium",
99
+ "large"
100
+ ]
39
101
  },
40
102
  "elevation": {
41
103
  "type": "object",
42
104
  "properties": {
105
+ "none": {
106
+ "type": "number"
107
+ },
108
+ "low": {
109
+ "type": "number"
110
+ },
111
+ "medium": {
112
+ "type": "number"
113
+ },
114
+ "high": {
115
+ "type": "number"
116
+ }
43
117
  },
44
- "required": []
118
+ "required": [
119
+ "none",
120
+ "low",
121
+ "medium",
122
+ "high"
123
+ ]
45
124
  }
46
125
  },
47
- "required": ["colors", "typography", "spacing", "borderRadius", "elevation"]
126
+ "required": [
127
+ "colors",
128
+ "typography",
129
+ "spacing",
130
+ "borderRadius",
131
+ "elevation"
132
+ ]
48
133
  }
@@ -25,6 +25,12 @@ class BrandSettingsValidator
25
25
 
26
26
  brands.each do |brand|
27
27
  brand_key = brand['key']
28
+
29
+ unless File.exist?(FilePath.brand(brand_key))
30
+ Solara.logger.fatal("#{brand_key} not found in #{FilePath.brands}")
31
+ next
32
+ end
33
+
28
34
  property_value = fetch_json_property(property_name, FilePath.public_send(file_path_method, brand_key))
29
35
 
30
36
  if property_value.to_s.strip.empty?
@@ -8,7 +8,8 @@ class BrandSettingsValidatorManager
8
8
  issues = ios_config
9
9
  issues += ios_signing
10
10
  issues += android_config
11
- issues + android_signing
11
+ issues += android_signing
12
+ issues + brand_config
12
13
  end
13
14
 
14
15
  def ios_config
@@ -17,16 +18,6 @@ class BrandSettingsValidatorManager
17
18
  :ios_config,
18
19
  issue_type: Issue::ERROR)
19
20
 
20
- issues += @validator.validate_single_property(
21
- 'PRODUCT_NAME',
22
- :ios_config,
23
- issue_type: Issue::ERROR)
24
-
25
- issues += @validator.validate_property_duplicates(
26
- 'PRODUCT_NAME',
27
- :ios_config,
28
- issue_type: Issue::WARNING)
29
-
30
21
  issues += @validator.validate_single_property(
31
22
  'PRODUCT_BUNDLE_IDENTIFIER',
32
23
  :ios_config,
@@ -58,16 +49,6 @@ class BrandSettingsValidatorManager
58
49
  :android_config,
59
50
  issue_type: Issue::ERROR)
60
51
 
61
- issues += @validator.validate_single_property(
62
- 'brandName',
63
- :android_config,
64
- issue_type: Issue::ERROR)
65
-
66
- issues += @validator.validate_property_duplicates(
67
- 'brandName',
68
- :android_config,
69
- issue_type: Issue::WARNING)
70
-
71
52
  issues += @validator.validate_single_property(
72
53
  'applicationId',
73
54
  :android_config,
@@ -79,4 +60,11 @@ class BrandSettingsValidatorManager
79
60
  issue_type: Issue::ERROR)
80
61
  end
81
62
 
63
+ def brand_config
64
+ @validator.validate_single_property(
65
+ 'brandName',
66
+ :brand_config,
67
+ issue_type: Issue::ERROR)
68
+ end
69
+
82
70
  end
@@ -2,10 +2,17 @@ structure:
2
2
  android:
3
3
  type: directory
4
4
  contents:
5
- assets:
6
- type: directory
7
5
  res:
8
6
  type: directory
7
+ contents:
8
+ values:
9
+ type: directory
10
+ contents:
11
+ strings.xml:
12
+ type: file
13
+ validations:
14
+ - type: content_includes
15
+ value: <string name="app_name">
9
16
  android_config.json:
10
17
  type: file
11
18
  validations:
@@ -21,8 +28,6 @@ structure:
21
28
  ios:
22
29
  type: directory
23
30
  contents:
24
- assets:
25
- type: directory
26
31
  ios_config.json:
27
32
  type: file
28
33
  validations:
@@ -35,6 +40,17 @@ structure:
35
40
  - type: valid_json
36
41
  - type: json_schema
37
42
  schema_path: platform/ios/ios_signing.json
43
+ InfoPlist.xcstrings:
44
+ type: file
45
+ validations:
46
+ - type: valid_json
47
+ - type: json_schema
48
+ schema_path: platform/ios/InfoPlist.xcstrings
49
+ xcassets:
50
+ type: directory
51
+ contents:
52
+ AppIcon.appiconset:
53
+ type: directory
38
54
  shared:
39
55
  type: directory
40
56
  contents:
@@ -42,6 +58,8 @@ structure:
42
58
  type: file
43
59
  validations:
44
60
  - type: valid_json
61
+ - type: json_schema
62
+ schema_path: platform/shared/brand_config.json
45
63
  theme.json:
46
64
  type: file
47
65
  validations: