solara 0.3.0 → 0.5.0

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/solara/lib/.DS_Store +0 -0
  3. data/solara/lib/core/.DS_Store +0 -0
  4. data/solara/lib/core/brands/brand_switcher.rb +58 -1
  5. data/solara/lib/core/dashboard/.DS_Store +0 -0
  6. data/solara/lib/core/dashboard/brand/BrandDetail.js +34 -2
  7. data/solara/lib/core/dashboard/brand/BrandDetailController.js +23 -206
  8. data/solara/lib/core/dashboard/brand/BrandDetailModel.js +13 -5
  9. data/solara/lib/core/dashboard/brand/BrandDetailView.js +16 -178
  10. data/solara/lib/core/dashboard/brand/SectionsFormManager.js +232 -0
  11. data/solara/lib/core/dashboard/brand/brand.html +199 -199
  12. data/solara/lib/core/dashboard/brand/source/BrandLocalSource.js +2 -5
  13. data/solara/lib/core/dashboard/brand/source/BrandRemoteSource.js +36 -133
  14. data/solara/lib/core/dashboard/brands/Brands.js +31 -0
  15. data/solara/lib/core/dashboard/brands/BrandsController.js +0 -5
  16. data/solara/lib/core/dashboard/brands/BrandsView.js +2 -2
  17. data/solara/lib/core/dashboard/brands/brands.html +71 -52
  18. data/solara/lib/core/dashboard/component/AliasesBottomSheet.js +6 -6
  19. data/solara/lib/core/dashboard/component/BrandOptionsBottomSheet.js +4 -4
  20. data/solara/lib/core/dashboard/component/ConfirmationDialog.js +15 -10
  21. data/solara/lib/core/dashboard/component/EditJsonSheet.js +160 -0
  22. data/solara/lib/core/dashboard/component/MessageBottomSheet.js +5 -5
  23. data/solara/lib/core/dashboard/component/OnboardBrandBottomSheet.js +5 -3
  24. data/solara/lib/core/dashboard/handler/base_handler.rb +1 -0
  25. data/solara/lib/core/dashboard/handler/edit_section_handler.rb +1 -5
  26. data/solara/lib/core/doctor/schema/brand_configurations.json +0 -8
  27. data/solara/lib/core/doctor/schema/platform/global/resources_manifest.json +30 -0
  28. data/solara/lib/core/doctor/schema/platform/json_manifest.json +57 -0
  29. data/solara/lib/core/doctor/validator/template/android_template_validation_config.yml +35 -1
  30. data/solara/lib/core/doctor/validator/template/flutter_template_validation_config.yml +30 -1
  31. data/solara/lib/core/doctor/validator/template/ios_template_validation_config.yml +35 -1
  32. data/solara/lib/core/doctor/validator/template/template_validator.rb +9 -9
  33. data/solara/lib/core/scripts/brand_config_manager.rb +1 -1
  34. data/solara/lib/core/scripts/brand_configurations_manager.rb +41 -0
  35. data/solara/lib/core/scripts/code_generator.rb +342 -118
  36. data/solara/lib/core/scripts/file_path.rb +21 -1
  37. data/solara/lib/core/scripts/gitignore_manager.rb +11 -3
  38. data/solara/lib/core/scripts/json_manifest_processor.rb +95 -0
  39. data/solara/lib/core/scripts/platform/ios/infoplist_string_catalog_manager.rb +11 -1
  40. data/solara/lib/core/scripts/resource_manifest_processor.rb +151 -0
  41. data/solara/lib/core/scripts/solara_status_manager.rb +1 -1
  42. data/solara/lib/core/scripts/theme_generator.rb +21 -242
  43. data/solara/lib/core/solara_configurator.rb +1 -1
  44. data/solara/lib/core/template/brands/global/resources_manifest.json +10 -0
  45. data/solara/lib/core/template/brands/json/Json-Manifest.md +61 -0
  46. data/solara/lib/core/template/brands/json/json_manifest.json +18 -0
  47. data/solara/lib/core/template/brands/shared/theme.json +213 -29
  48. data/solara/lib/core/template/config/android_template_config.json +50 -0
  49. data/solara/lib/core/template/config/flutter_template_config.json +35 -0
  50. data/solara/lib/core/template/config/ios_template_config.json +50 -0
  51. data/solara/lib/core/template/configurations.json +46 -0
  52. data/solara/lib/core/template/project_template_generator.rb +2 -0
  53. data/solara/lib/solara/version.rb +1 -1
  54. data/solara/lib/solara.rb +19 -0
  55. metadata +13 -4
  56. data/solara/lib/core/dashboard/component/AddFieldSheet.js +0 -175
  57. data/solara/lib/core/dashboard/handler/brand_configurations_manager.rb +0 -73
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a886519a93f39b2e87df6f2f427fa72e6baf9d4f3520424a7c86c207cb684e56
4
- data.tar.gz: e5f0f1673493a4177eaf70ba1af01ef6de900074f8c934c6b15600197f2af474
3
+ metadata.gz: 714797cd507e354e49c4a1981a516f6ad3e659797ba40b6040c7e7a6f30f11aa
4
+ data.tar.gz: 3b3d4ed6c116abea9dd15c2db4b5df308320649be4381623e3c7a3c863ef0385
5
5
  SHA512:
6
- metadata.gz: cd784de6b07c8208c290f6cdb00827e0aa2e44f0f10d19e584592bca6d1aa2d7c7bb195c599286500dbacb71662956b6247f1fb7ca82daf40f0c60ab0022e4ad
7
- data.tar.gz: 0e920bd5ba5938eac7933c40708df506762620bb3466ff743851361f414845d396c363e66145008b3b46a539ca3633f2117ecee6c44cc862764f3014112a8df6
6
+ metadata.gz: b4c46c3f893d95eddbde530e7d83fe340ce36698974880073b3517779bb8e39b31813863c13f7743e821936b814e6d7f5d42337c10b3ef37a4cd6767732f5a20
7
+ data.tar.gz: 750e7851fa9584bb85b00b5f01e48ea246892914f1bbfafeb7a2b18db8e138d0da5f8fd2a2253434bed1dd6b6d9b0c6911dcaec908714e96ff69c894653490b8
data/solara/lib/.DS_Store CHANGED
Binary file
Binary file
@@ -30,6 +30,9 @@ class BrandSwitcher
30
30
  def switch
31
31
  BrandFontSwitcher.new(@brand_key).switch
32
32
 
33
+ ResourceManifestSwitcher.new(@brand_key).switch
34
+ JsonManifestSwitcher.new(@brand_key).switch
35
+
33
36
  case @platform
34
37
  when Platform::Flutter
35
38
  IOSBrandSwitcher.new(@brand_key).switch
@@ -42,6 +45,60 @@ class BrandSwitcher
42
45
  else
43
46
  raise ArgumentError, "Invalid platform: #{@platform}"
44
47
  end
48
+
49
+ end
50
+
51
+ end
52
+
53
+ class ResourceManifestSwitcher
54
+ def initialize(brand_key)
55
+ @brand_key = brand_key
56
+ end
57
+
58
+ def switch
59
+ Solara.logger.start_step("Process resource manifest: #{FilePath.resources_manifest}")
60
+ brand_resource_copier = ResourceManifestProcessor.new(@brand_key)
61
+ brand_resource_copier.copy
62
+ Solara.logger.debug("#{@brand_key} resources copied successfully according to the manifest: #{FilePath.resources_manifest}.")
63
+ Solara.logger.end_step("Process resource manifest: #{FilePath.resources_manifest}")
64
+ end
65
+
66
+ end
67
+
68
+ class JsonManifestSwitcher
69
+ def initialize(brand_key)
70
+ @brand_key = brand_key
71
+ @manifest_path = FilePath.brand_json_dir(brand_key)
72
+ end
73
+
74
+ def switch
75
+ Solara.logger.start_step("Process JSON manifest: #{@manifest_path}")
76
+
77
+
78
+ case SolaraSettingsManager.instance.platform
79
+ when Platform::Flutter
80
+ process_maifest(Language::Dart, FilePath.flutter_lib_artifacts)
81
+ process_maifest(Language::Dart, FilePath.brand_global_json_dir)
82
+ when Platform::IOS
83
+ process_maifest(Language::Swift, FilePath.ios_project_root_artifacts)
84
+ process_maifest(Language::Swift, FilePath.brand_global_json_dir)
85
+ when Platform::Android
86
+ process_maifest(Language::Kotlin, FilePath.android_project_java_artifacts )
87
+ process_maifest(Language::Kotlin, FilePath.brand_global_json_dir)
88
+ else
89
+ raise ArgumentError, "Invalid platform: #{@platform}"
90
+ end
91
+
92
+ Solara.logger.end_step("Process JSON manifest: #{@manifest_path}")
93
+ end
94
+
95
+ def process_maifest(language, output_path)
96
+ processor = JsonManifestProcessor.new(
97
+ @manifest_path,
98
+ language,
99
+ output_path
100
+ )
101
+ processor.process
45
102
  end
46
103
  end
47
104
 
@@ -225,7 +282,7 @@ class ThemeSwitcher
225
282
  def generate_theme(name, language, platform)
226
283
  Solara.logger.start_step("Generate #{name} for #{platform}")
227
284
 
228
- theme_manager = ThemeGeneratorManager.new(FilePath.brand_theme(@brand_key))
285
+ theme_manager = ThemeGenerator.new(FilePath.brand_theme(@brand_key))
229
286
  theme_manager.generate(language, FilePath.generated_config(name, platform))
230
287
 
231
288
  Solara.logger.end_step("Generate #{name} for #{platform}")
Binary file
@@ -2,6 +2,37 @@ import BrandDetailModel from './BrandDetailModel.js';
2
2
  import BrandDetailView from './BrandDetailView.js';
3
3
  import BrandDetailController from './BrandDetailController.js';
4
4
 
5
+ const modeToggle = document.getElementById('modeToggle');
6
+ const body = document.body;
7
+ const icon = modeToggle.querySelector('i');
8
+
9
+ function applyMode(mode) {
10
+ if (mode === 'dark') {
11
+ body.classList.add('dark-mode');
12
+ icon.classList.remove('fa-sun');
13
+ icon.classList.add('fa-moon');
14
+ } else {
15
+ body.classList.remove('dark-mode');
16
+ icon.classList.remove('fa-moon');
17
+ icon.classList.add('fa-sun');
18
+ }
19
+ }
20
+
21
+ const savedMode = localStorage.getItem('mode');
22
+ if (savedMode) {
23
+ applyMode(savedMode);
24
+ } else {
25
+ const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
26
+ applyMode(systemPrefersDark ? 'dark' : 'light');
27
+ }
28
+
29
+ modeToggle.addEventListener('click', () => {
30
+ const currentMode = body.classList.contains('dark-mode') ? 'dark' : 'light';
31
+ const newMode = currentMode === 'dark' ? 'light' : 'dark';
32
+ applyMode(newMode);
33
+ localStorage.setItem('mode', newMode);
34
+ });
35
+
5
36
  window.onload = function () {
6
37
  document.getElementById('loadingOverlay').style.display = 'none';
7
38
  };
@@ -20,10 +51,11 @@ window.addEventListener('scroll', function () {
20
51
  }
21
52
  lastScrollTop = scrollTop;
22
53
  });
23
-
54
+
24
55
  document.addEventListener('DOMContentLoaded', async () => {
25
56
  const model = new BrandDetailModel();
26
57
  const view = new BrandDetailView(model);
27
58
  const controller = new BrandDetailController(model, view);
28
59
  await controller.initializeApp();
29
- });
60
+ });
61
+
@@ -1,15 +1,10 @@
1
1
  import {DataSource} from './BrandDetailModel.js';
2
- import InfoPlistStringCatalogManager from "./InfoPlistStringCatalogManager.js";
3
2
 
4
3
  class BrandDetailController {
5
4
  constructor(model, view) {
6
5
  this.model = model;
7
6
  this.view = view;
8
- this.onSectionChanged = this.onSectionChanged.bind(this);
9
- this.deleteField = this.deleteField.bind(this);
10
7
  this.initializeEventListeners();
11
- this.view.setOnSectionChangedHandler(this.onSectionChanged.bind(this));
12
- this.view.setOnDeleteFieldHandler(this.deleteField.bind(this));
13
8
  }
14
9
 
15
10
  async initializeApp() {
@@ -80,8 +75,7 @@ class BrandDetailController {
80
75
 
81
76
  async addNewBrand() {
82
77
  this.view.showOnboardBrandForm(async (key, name) => {
83
- const configurations = await this.model.createNewBrandConfogurations()
84
- console.log(configurations)
78
+ const configurations = await this.model.createNewBrandConfigurations()
85
79
  await this.addBrand(key, name, configurations)
86
80
  })
87
81
  }
@@ -98,10 +92,10 @@ class BrandDetailController {
98
92
  await this.onLoadSections(response.result);
99
93
  const {isCurrentBrand, contentChanged} = await this.model.fetchCurrentBrand();
100
94
 
101
- if (!isCurrentBrand) {
95
+ if (isCurrentBrand) {
96
+ this.view.setupSyncBrandButton(contentChanged ? '#ff4136' : '#4A90E2');
97
+ } else {
102
98
  this.view.showSwitchButton();
103
- } else if (contentChanged) {
104
- this.view.showApplyChangesButton();
105
99
  }
106
100
 
107
101
  await this.checkBrandHealth();
@@ -129,7 +123,12 @@ class BrandDetailController {
129
123
  window.location.href = `../brands/brands.html?source=${this.model.source}`;
130
124
  });
131
125
 
132
- document.getElementById('applyChangesButton').addEventListener('click', () => this.switchToBrand());
126
+ document.getElementById('syncBrandButton').addEventListener(
127
+ 'click',
128
+ async () => {
129
+ await this.switchToBrand()
130
+ await this.view.toast("Synced successfully")
131
+ });
133
132
  document.getElementById('switchButton').addEventListener('click', () => this.switchToBrand());
134
133
 
135
134
  this.view.exportBrandBtn.addEventListener('click', () => this.exportBrand());
@@ -142,155 +141,37 @@ class BrandDetailController {
142
141
 
143
142
  const sectionItems = configuraationsResult.configurations
144
143
 
145
- for (let i = 0; i < sectionItems.length; i++) {
146
- const sectionInfo = sectionItems[i];
147
- console.log('Processing section:', i, sectionInfo);
148
-
149
- if (sectionInfo.key === 'theme.json') {
150
- this.createThemeSections(sectionInfo)
151
- } else if (sectionInfo.key === 'InfoPlist.xcstrings') {
152
- this.createSection(
153
- sectionInfo.key,
154
- sectionInfo,
155
- new InfoPlistStringCatalogManager(sectionInfo.content).extractLocalizations(),
156
- sectionInfo.name,
157
- sectionInfo.inputType)
158
- } else {
159
- this.createSection(sectionInfo.key, sectionInfo, sectionInfo.content, sectionInfo.name, sectionInfo.inputType)
160
- }
161
- }
144
+ this.view.sectionsFormManager.display(
145
+ sectionItems,
146
+ (section, container) => {
147
+ this.onSectionChanged(section, container)
148
+ })
149
+
162
150
  } catch (error) {
163
151
  console.error('Error loading configurations:', error);
164
152
  alert(error.message);
165
153
  }
166
154
  }
167
155
 
168
- createThemeSections(sectionInfo) {
169
- this.createSection(`${sectionInfo.key}_colors`,
170
- sectionInfo,
171
- sectionInfo.content.colors,
172
- 'Theme Colors',
173
- 'color',
174
- 'colors')
175
- this.createSection(`${sectionInfo.key}_typography`,
176
- sectionInfo,
177
- sectionInfo.content.typography,
178
- 'Theme Typography',
179
- 'text',
180
- 'typography')
181
- this.createSection(`${sectionInfo.key}_spacing`,
182
- sectionInfo,
183
- sectionInfo.content.spacing,
184
- 'Theme Spacing', 'text',
185
- 'spacing')
186
- this.createSection(
187
- `${sectionInfo.key}_borderRadius`,
188
- sectionInfo,
189
- sectionInfo.content.borderRadius,
190
- 'Theme Border Radius',
191
- 'text',
192
- 'borderRadius')
193
- this.createSection(
194
- `${sectionInfo.key}_elevation`,
195
- sectionInfo,
196
- sectionInfo.content.elevation,
197
- 'Theme Elevation',
198
- 'text',
199
- 'elevation')
200
- }
201
-
202
- createSection(id, sectionInfo, content, sectionName, inputType, propertiesGroupName = null) {
203
- const sectionElement = this.view.createSection(sectionInfo.key, sectionName, inputType);
204
- sectionElement.id = id;
205
- sectionElement.dataset.propertiesGroupName = propertiesGroupName
206
-
207
- this.view.sectionsContainer.appendChild(sectionElement);
208
-
209
- console.log('Section element created:', sectionElement);
210
-
211
- this.view.populateSection(sectionInfo, sectionElement, content, inputType);
212
-
213
- const addButton = document.createElement('button');
214
- addButton.textContent = 'Add Field';
215
- addButton.className = 'add-field-btn';
216
- addButton.onclick = () => this.addNewField(sectionInfo, sectionElement, inputType);
217
- sectionElement.appendChild(addButton);
218
- }
156
+ async onSectionChanged(section, container) {
157
+ if (this.model.isRemote()) return
219
158
 
220
- async onSectionChanged(sectionItem, sectionElement) {
221
159
  try {
222
- const configuration = await this.getSectionData(sectionElement.dataset.key)
223
- await this.model.saveSection(sectionItem, configuration);
224
- this.view.showApplyChangesButton();
160
+ await this.model.saveSection(container.dataset.key, section.content);
225
161
  await this.checkBrandHealth();
162
+ await this.switchToBrand(true)
226
163
  } catch (error) {
227
164
  console.error('Error saving section:', error);
228
165
  alert(error.message);
229
166
  }
230
167
  }
231
168
 
232
- getSectionConfiguration(sectionElement) {
233
- const configuration = {};
234
- const inputs = sectionElement.querySelectorAll('input:not(.array-item-input)');
235
- inputs.forEach(input => {
236
- const keys = input.id.split('.');
237
- let current = configuration;
238
- for (let i = 0; i < keys.length - 1; i++) {
239
- if (!current[keys[i]]) {
240
- current[keys[i]] = {};
241
- }
242
- current = current[keys[i]];
243
- }
244
- const lastKey = keys[keys.length - 1];
245
-
246
- if (input.classList.contains('array-input')) {
247
- const arrayItemsContainer = input.closest('.input-wrapper').querySelector('.array-items-container');
248
- current[lastKey] = this.getArrayValue(arrayItemsContainer);
249
- } else if (input.type === 'checkbox') {
250
- current[lastKey] = input.checked;
251
- } else {
252
- let value = input.value;
253
- if (input.type === 'color') {
254
- value = `#${value.substring(1).toUpperCase()}`;
255
- } else if (!isNaN(value) && value.trim() !== '') {
256
- // Convert to number if it's a valid number string
257
- value = parseFloat(value);
258
- }
259
- current[lastKey] = value;
260
- }
261
- });
262
- return configuration;
263
- }
264
-
265
- addNewField(sectionItem, sectionElement, inputType) {
266
- this.view.showAddFieldForm(sectionItem, sectionElement, inputType);
267
- }
268
-
269
- deleteField(sectionItem, fieldContainer) {
270
- this.view.showConfirmationDialog(
271
- 'Are you sure you want to delete this item?',
272
- () => {
273
- const sectionElement = fieldContainer.closest('.section');
274
- fieldContainer.remove();
275
- this.onSectionChanged(sectionItem, sectionElement);
276
- }
277
- );
278
- }
279
-
280
- getArrayValue(container) {
281
- const arrayItems = container.querySelectorAll('.array-item-input');
282
- return Array.from(arrayItems).map(item => item.value);
283
- }
284
-
285
- async switchToBrand() {
169
+ async switchToBrand(silentError = false) {
286
170
  try {
287
171
  await this.model.switchToBrand();
288
- const applyChangesButton = document.getElementById('applyChangesButton');
289
- applyChangesButton.style.display = 'none';
290
- location.reload();
291
172
  } catch (error) {
292
173
  console.error('Error switching to brand:', error);
293
- alert(error.message);
174
+ if (!silentError) alert(error.message);
294
175
  }
295
176
  }
296
177
 
@@ -318,76 +199,13 @@ class BrandDetailController {
318
199
  }
319
200
  }
320
201
 
321
- async getSectionData(sectionKey) {
322
- try {
323
- const container = this.view.sectionsContainer;
324
-
325
- const sectionElements = Array.from(container.querySelectorAll('.section'))
326
- .filter(element => element.dataset.key === sectionKey);
327
-
328
- if (sectionElements.length === 1) {
329
- return this.getSectionConfiguration(sectionElements[0])
330
- }
331
-
332
- const configurations = sectionElements.map(sectionElement => {
333
- const propertiesGroupName = sectionElement.dataset.propertiesGroupName;
334
- const config = this.getSectionConfiguration(sectionElement);
335
-
336
- if (propertiesGroupName !== "null") {
337
- return {[propertiesGroupName]: config};
338
- } else {
339
- return config;
340
- }
341
- });
342
-
343
- const result = configurations.reduce((acc, config) => {
344
- const key = Object.keys(config)[0]; // Get the key from the configuration item
345
- acc[key] = config[key]; // Assign the value to the dynamic object
346
- return acc;
347
- }, {});
348
-
349
- const json = JSON.stringify(result, null, 2); // Pretty-printing JSON
350
- console.log(json);
351
- return result;
352
-
353
- } catch (error) {
354
- console.error('Error downloading brand:', error);
355
- alert(error.message);
356
- }
357
- }
358
-
359
202
  async exportBrand() {
360
203
  try {
361
- const sectionsContainer = this.view.sectionsContainer;
204
+ const result = this.view.sectionsFormManager.data();
362
205
 
363
206
  const brandKey = this.view.sectionsContainer.dataset.brandKey;
364
207
  const brandName = this.view.sectionsContainer.dataset.brandName;
365
208
 
366
- const sectionElements = Array.from(sectionsContainer.querySelectorAll('.section'));
367
-
368
- const uniqueSections = new Map();
369
-
370
- // The theme section has been divided into multiple categories (e.g., colors, typography).
371
- // In the getSectionData function, we merge these sections. To prevent duplication when
372
- // processing the sections, we will ensure that each section key is processed only once.
373
- await Promise.all(sectionElements.map(async sectionElement => {
374
- const key = sectionElement.dataset.key;
375
- // Check if the key already exists in the map
376
- if (!uniqueSections.has(key)) {
377
- const configurations = await this.getSectionData(key);
378
- uniqueSections.set(
379
- key, {
380
- key: key,
381
- name: sectionElement.dataset.name,
382
- inputType: sectionElement.dataset.inputType,
383
- content: configurations
384
- });
385
- }
386
- }));
387
-
388
- // Convert the map values to an array
389
- const result = Array.from(uniqueSections.values());
390
-
391
209
  this.model.exportBrand(brandKey, brandName, result);
392
210
 
393
211
  } catch (error) {
@@ -399,5 +217,4 @@ class BrandDetailController {
399
217
  }
400
218
 
401
219
 
402
-
403
220
  export default BrandDetailController;
@@ -17,6 +17,14 @@ class BrandDetailModel {
17
17
  this.source = sourceFromUrl === DataSource.LOCAL ? DataSource.LOCAL : DataSource.REMOTE;
18
18
  }
19
19
 
20
+ isLocal() {
21
+ return this.source === DataSource.LOCAL
22
+ }
23
+
24
+ isRemote() {
25
+ return this.source === DataSource.REMOTE
26
+ }
27
+
20
28
  getQueryFromUrl(name) {
21
29
  return this.localSource.getQueryFromUrl(name);
22
30
  }
@@ -29,10 +37,10 @@ class BrandDetailModel {
29
37
  return await this.localSource.fetchCurrentBrand(this.brandKey);
30
38
  }
31
39
 
32
- async saveSection(sectionItem, configuration) {
40
+ async saveSection(key, configuration) {
33
41
  switch (this.source) {
34
42
  case DataSource.LOCAL:
35
- return await this.localSource.saveSection(sectionItem, configuration, this.brandKey);
43
+ return await this.localSource.saveSection(key, configuration, this.brandKey);
36
44
  case DataSource.REMOTE:
37
45
  // Saving is not supported remotely. Instead, user can export the brand.
38
46
  return
@@ -48,7 +56,7 @@ class BrandDetailModel {
48
56
  async checkBrandHealth() {
49
57
  switch (this.source) {
50
58
  case DataSource.LOCAL:
51
- return await this.localSource.checkBrandHealth(this.brandKey);
59
+ return await this.localSource.checkBrandHealth(this.brandKey);
52
60
  case DataSource.REMOTE:
53
61
  // Checking health is not supported remotely yet.
54
62
  return
@@ -57,8 +65,8 @@ class BrandDetailModel {
57
65
  }
58
66
  }
59
67
 
60
- async createNewBrandConfogurations() {
61
- return await this.remoteSource.createNewBrandConfogurations();
68
+ async createNewBrandConfigurations() {
69
+ return await this.remoteSource.createNewBrandConfigurations();
62
70
  }
63
71
 
64
72
  async createBrandConfigurationsFromDirectory(dirHandle) {