solara 0.4.0 → 0.6.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.
- checksums.yaml +4 -4
- data/solara/lib/.DS_Store +0 -0
- data/solara/lib/core/.DS_Store +0 -0
- data/solara/lib/core/brands/brand_onboarder.rb +1 -1
- data/solara/lib/core/brands/brand_switcher.rb +92 -1
- data/solara/lib/core/dashboard/brand/BrandDetail.js +34 -2
- data/solara/lib/core/dashboard/brand/BrandDetailController.js +27 -234
- data/solara/lib/core/dashboard/brand/BrandDetailModel.js +14 -5
- data/solara/lib/core/dashboard/brand/BrandDetailView.js +16 -200
- data/solara/lib/core/dashboard/brand/SectionsFormManager.js +293 -0
- data/solara/lib/core/dashboard/brand/brand.html +223 -174
- data/solara/lib/core/dashboard/brand/source/BrandLocalSource.js +2 -5
- data/solara/lib/core/dashboard/brand/source/BrandRemoteSource.js +36 -133
- data/solara/lib/core/dashboard/brands/Brands.js +31 -0
- data/solara/lib/core/dashboard/brands/BrandsController.js +0 -5
- data/solara/lib/core/dashboard/brands/BrandsView.js +2 -2
- data/solara/lib/core/dashboard/brands/brands.html +71 -52
- data/solara/lib/core/dashboard/component/AliasesBottomSheet.js +6 -6
- data/solara/lib/core/dashboard/component/BrandOptionsBottomSheet.js +4 -4
- data/solara/lib/core/dashboard/component/ConfirmationDialog.js +15 -10
- data/solara/lib/core/dashboard/component/EditJsonSheet.js +160 -0
- data/solara/lib/core/dashboard/component/MessageBottomSheet.js +5 -5
- data/solara/lib/core/dashboard/component/OnboardBrandBottomSheet.js +9 -3
- data/solara/lib/core/dashboard/handler/base_handler.rb +1 -0
- data/solara/lib/core/dashboard/handler/edit_section_handler.rb +1 -5
- data/solara/lib/core/dashboard/handler/onboard_brand_handler.rb +0 -15
- data/solara/lib/core/doctor/schema/brand_configurations.json +0 -8
- data/solara/lib/core/doctor/schema/platform/global/resources_manifest.json +30 -0
- data/solara/lib/core/doctor/schema/platform/json_manifest.json +39 -0
- data/solara/lib/core/doctor/validator/template/android_template_validation_config.yml +35 -1
- data/solara/lib/core/doctor/validator/template/flutter_template_validation_config.yml +30 -1
- data/solara/lib/core/doctor/validator/template/ios_template_validation_config.yml +35 -1
- data/solara/lib/core/doctor/validator/template/template_validator.rb +9 -9
- data/solara/lib/core/scripts/brand_config_manager.rb +1 -1
- data/solara/lib/core/scripts/brand_configurations_manager.rb +41 -0
- data/solara/lib/core/scripts/code_generator.rb +342 -118
- data/solara/lib/core/scripts/file_manager.rb +11 -15
- data/solara/lib/core/scripts/file_path.rb +21 -1
- data/solara/lib/core/scripts/gitignore_manager.rb +12 -6
- data/solara/lib/core/scripts/json_manifest_processor.rb +136 -0
- data/solara/lib/core/scripts/platform/ios/infoplist_string_catalog_manager.rb +11 -1
- data/solara/lib/core/scripts/resource_manifest_processor.rb +151 -0
- data/solara/lib/core/scripts/solara_status_manager.rb +1 -1
- data/solara/lib/core/scripts/theme_generator.rb +21 -242
- data/solara/lib/core/solara_configurator.rb +1 -1
- data/solara/lib/core/template/brands/global/resources_manifest.json +10 -0
- data/solara/lib/core/template/brands/json/Json-Manifest.md +59 -0
- data/solara/lib/core/template/brands/json/json_manifest.json +16 -0
- data/solara/lib/core/template/brands/shared/theme.json +213 -29
- data/solara/lib/core/template/config/android_template_config.json +50 -0
- data/solara/lib/core/template/config/flutter_template_config.json +35 -0
- data/solara/lib/core/template/config/ios_template_config.json +50 -0
- data/solara/lib/core/template/configurations.json +46 -0
- data/solara/lib/core/template/project_template_generator.rb +2 -0
- data/solara/lib/solara/version.rb +1 -1
- data/solara/lib/solara.rb +19 -0
- data/solara/lib/solara_manager.rb +21 -13
- metadata +13 -4
- data/solara/lib/core/dashboard/component/AddFieldSheet.js +0 -175
- data/solara/lib/core/dashboard/handler/brand_configurations_manager.rb +0 -73
@@ -7,25 +7,29 @@ class ConfirmationDialog extends HTMLElement {
|
|
7
7
|
|
8
8
|
render() {
|
9
9
|
this.shadowRoot.innerHTML = `
|
10
|
-
|
10
|
+
<style>
|
11
|
+
.title {
|
12
|
+
color: var(--text-color);
|
13
|
+
font-size: 14px;
|
14
|
+
}
|
11
15
|
.confirmation-dialog {
|
12
16
|
display: none;
|
13
17
|
position: fixed;
|
14
18
|
top: 50%;
|
15
19
|
left: 50%;
|
16
20
|
transform: translate(-50%, -50%);
|
17
|
-
background-color:
|
18
|
-
padding: 14px;
|
21
|
+
background-color: var(--background-color);
|
19
22
|
border-radius: 7px;
|
20
23
|
box-shadow: 0 2.8px 4.2px rgba(0, 0, 0, 0.1);
|
21
24
|
z-index: 1001;
|
22
25
|
text-align: center;
|
23
|
-
font-size:
|
26
|
+
font-size: 11px;
|
27
|
+
padding: 20px;
|
24
28
|
}
|
25
29
|
.confirmation-dialog h3 {
|
26
30
|
margin-top: 0;
|
27
31
|
color: var(--primary-color);
|
28
|
-
font-size:
|
32
|
+
font-size: 15px;
|
29
33
|
}
|
30
34
|
.confirmation-dialog .buttons {
|
31
35
|
margin-top: 14px;
|
@@ -42,16 +46,18 @@ class ConfirmationDialog extends HTMLElement {
|
|
42
46
|
.confirmation-dialog .confirm {
|
43
47
|
background-color: #dc3545;
|
44
48
|
color: white;
|
49
|
+
margin-top: 10px;
|
45
50
|
}
|
46
51
|
.confirmation-dialog .cancel {
|
47
52
|
background-color: #ccc;
|
48
53
|
color: #333;
|
49
|
-
|
54
|
+
margin-top: 10px;
|
55
|
+
}
|
50
56
|
.confirmation-dialog .confirm:hover {
|
51
|
-
background-color:
|
57
|
+
background-color: var(--hover);
|
52
58
|
}
|
53
59
|
.confirmation-dialog .cancel:hover {
|
54
|
-
background-color:
|
60
|
+
background-color: var(--hover);
|
55
61
|
}
|
56
62
|
.overlay {
|
57
63
|
display: none;
|
@@ -66,8 +72,7 @@ class ConfirmationDialog extends HTMLElement {
|
|
66
72
|
</style>
|
67
73
|
<div class="overlay" id="overlay"></div>
|
68
74
|
<div class="confirmation-dialog" id="confirmationDialog">
|
69
|
-
<
|
70
|
-
<p id="confirmationMessage"></p>
|
75
|
+
<h2 class="title" id="confirmationMessage"></h2>
|
71
76
|
<div class="buttons">
|
72
77
|
<button class="confirm" id="confirmButton">Confirm</button>
|
73
78
|
<button class="cancel" id="cancelButton">Cancel</button>
|
@@ -0,0 +1,160 @@
|
|
1
|
+
class EditJsonSheet extends HTMLElement {
|
2
|
+
constructor() {
|
3
|
+
super();
|
4
|
+
this.onSubmit = null;
|
5
|
+
this.attachShadow({mode: 'open'});
|
6
|
+
this.render();
|
7
|
+
|
8
|
+
this.sheet = this.shadowRoot.querySelector('#sheet');
|
9
|
+
this.overlay = this.shadowRoot.getElementById('overlay');
|
10
|
+
this.titleText = this.shadowRoot.getElementById('title');
|
11
|
+
this.valueInput = this.shadowRoot.querySelector('#valueInput');
|
12
|
+
|
13
|
+
this.shadowRoot.querySelector('#editJsonSheet').onsubmit = (e) => this.handleSubmit(e);
|
14
|
+
this.overlay.onclick = () => this.hideSheet();
|
15
|
+
}
|
16
|
+
|
17
|
+
render() {
|
18
|
+
this.shadowRoot.innerHTML = `
|
19
|
+
<style>
|
20
|
+
.bottom-sheet {
|
21
|
+
display: flex;
|
22
|
+
flex-direction: column; /* Stack children vertically */
|
23
|
+
position: fixed;
|
24
|
+
bottom: -100%;
|
25
|
+
left: 0;
|
26
|
+
right: 0;
|
27
|
+
background-color: var(--background-color);
|
28
|
+
padding: 21px;
|
29
|
+
box-shadow: 0 -3.5px 14px rgba(0, 0, 0, 0.2);
|
30
|
+
transition: bottom 0.3s ease-out;
|
31
|
+
z-index: 1000;
|
32
|
+
border-top-left-radius: 17.5px;
|
33
|
+
border-top-right-radius: 17.5px;
|
34
|
+
height: 70vh; /* Height set to 70% of viewport height */
|
35
|
+
overflow-y: auto; /* Enable scrolling if content overflows */
|
36
|
+
max-width: 60%;
|
37
|
+
margin: 0 auto;
|
38
|
+
align-items: stretch; /* Allow children to stretch */
|
39
|
+
}
|
40
|
+
.bottom-sheet.show {
|
41
|
+
bottom: 0;
|
42
|
+
}
|
43
|
+
.bottom-sheet h3 {
|
44
|
+
color: var(--primary-color);
|
45
|
+
margin-top: 0;
|
46
|
+
margin-bottom: 14px;
|
47
|
+
font-size: 16.8px;
|
48
|
+
}
|
49
|
+
.overlay {
|
50
|
+
display: none;
|
51
|
+
position: fixed;
|
52
|
+
top: 0;
|
53
|
+
left: 0;
|
54
|
+
right: 0;
|
55
|
+
bottom: 0;
|
56
|
+
background: rgba(0, 0, 0, 0.5);
|
57
|
+
z-index: 999;
|
58
|
+
}
|
59
|
+
.show {
|
60
|
+
display: block;
|
61
|
+
}
|
62
|
+
.sheet-title {
|
63
|
+
color: var(--text-color);
|
64
|
+
}
|
65
|
+
.form-group {
|
66
|
+
max-width: 98%;
|
67
|
+
margin-bottom: 14px;
|
68
|
+
flex-grow: 1; /* Allow form group to grow */
|
69
|
+
}
|
70
|
+
.form-group label {
|
71
|
+
display: block;
|
72
|
+
margin-bottom: 5.6px;
|
73
|
+
font-weight: bold;
|
74
|
+
font-size: 11.2px;
|
75
|
+
}
|
76
|
+
.form-group input, .form-group textarea {
|
77
|
+
padding: 8.4px;
|
78
|
+
border: 1px solid var(--border-color);
|
79
|
+
border-radius: 2.8px;
|
80
|
+
font-size: 11.2px;
|
81
|
+
width: 100%;
|
82
|
+
}
|
83
|
+
.form-group textarea {
|
84
|
+
height: 100%; /* Take 50% of the bottom-sheet height */
|
85
|
+
min-height: 300px; /* Ensure a minimum height */
|
86
|
+
resize: vertical; /* Allow vertical resizing */
|
87
|
+
font-family: monospace;
|
88
|
+
flex-grow: 1; /* Allow textarea to grow */
|
89
|
+
background-color: var(--background-color);
|
90
|
+
color: var(--text-color);
|
91
|
+
border: 1px solid var(--border-color);
|
92
|
+
}
|
93
|
+
.submit-button {
|
94
|
+
min-width: 30%;
|
95
|
+
display: block;
|
96
|
+
margin: 0 auto;
|
97
|
+
padding: 10.5px;
|
98
|
+
font-size: 12.6px;
|
99
|
+
background-color: var(--primary-color);
|
100
|
+
color: white;
|
101
|
+
border: none;
|
102
|
+
border-radius: 2.8px;
|
103
|
+
cursor: pointer;
|
104
|
+
transition: background-color 0.3s ease;
|
105
|
+
}
|
106
|
+
.submit-button:hover {
|
107
|
+
background-color: var(--hover);
|
108
|
+
}
|
109
|
+
</style>
|
110
|
+
|
111
|
+
<div id="overlay" class="overlay"></div>
|
112
|
+
<div class="bottom-sheet" id="sheet">
|
113
|
+
<h2 class="sheet-title" id="title"></h2>
|
114
|
+
<form id="editJsonSheet">
|
115
|
+
<div class="form-group">
|
116
|
+
<textarea id="valueInput" name="valueInput" placeholder='Enter a value' required></textarea>
|
117
|
+
</div>
|
118
|
+
<button type="submit" class="submit-button">Submit</button>
|
119
|
+
</form>
|
120
|
+
</div>
|
121
|
+
`;
|
122
|
+
}
|
123
|
+
|
124
|
+
show(value, title, onSubmit) {
|
125
|
+
this.titleText.textContent = title
|
126
|
+
this.onSubmit = onSubmit;
|
127
|
+
this.valueInput.value = value;
|
128
|
+
|
129
|
+
this.sheet.style.display = 'block';
|
130
|
+
this.overlay.classList.add('show');
|
131
|
+
setTimeout(() => this.sheet.classList.add('show'), 10);
|
132
|
+
}
|
133
|
+
|
134
|
+
hideSheet() {
|
135
|
+
this.sheet.classList.remove('show');
|
136
|
+
this.overlay.classList.remove('show');
|
137
|
+
setTimeout(() => {
|
138
|
+
this.sheet.style.display = 'none';
|
139
|
+
}, 300);
|
140
|
+
}
|
141
|
+
|
142
|
+
handleSubmit(e) {
|
143
|
+
e.preventDefault();
|
144
|
+
let valueInput = this.valueInput.value;
|
145
|
+
|
146
|
+
try {
|
147
|
+
let data = JSON.parse(valueInput)
|
148
|
+
this.onSubmit(data);
|
149
|
+
} catch (e) {
|
150
|
+
console.error("Invalid JSON:", e);
|
151
|
+
alert(e)
|
152
|
+
return;
|
153
|
+
}
|
154
|
+
|
155
|
+
this.hideSheet();
|
156
|
+
}
|
157
|
+
|
158
|
+
}
|
159
|
+
|
160
|
+
customElements.define('edit-json-sheet', EditJsonSheet);
|
@@ -10,7 +10,7 @@ class MessageBottomSheet extends HTMLElement {
|
|
10
10
|
bottom: 0;
|
11
11
|
left: 0;
|
12
12
|
right: 0;
|
13
|
-
background-color:
|
13
|
+
background-color: var(--background-color);
|
14
14
|
border-top-left-radius: 14px;
|
15
15
|
border-top-right-radius: 14px;
|
16
16
|
box-shadow: 0 -1.4px 7px rgba(0, 0, 0, 0.1);
|
@@ -18,7 +18,7 @@ class MessageBottomSheet extends HTMLElement {
|
|
18
18
|
padding: 14px;
|
19
19
|
transition: transform 0.3s ease-out;
|
20
20
|
transform: translateY(100%);
|
21
|
-
max-width:
|
21
|
+
max-width: 60%;
|
22
22
|
margin: 0 auto;
|
23
23
|
width: 100%;
|
24
24
|
}
|
@@ -26,7 +26,7 @@ class MessageBottomSheet extends HTMLElement {
|
|
26
26
|
transform: translateY(0);
|
27
27
|
}
|
28
28
|
.message-content {
|
29
|
-
max-height:
|
29
|
+
max-height: 50%;
|
30
30
|
overflow-y: auto;
|
31
31
|
margin-bottom: 14px;
|
32
32
|
}
|
@@ -42,7 +42,7 @@ class MessageBottomSheet extends HTMLElement {
|
|
42
42
|
font-size: 11.2px;
|
43
43
|
}
|
44
44
|
.close-message:hover {
|
45
|
-
background-color:
|
45
|
+
background-color: var(--hover);
|
46
46
|
}
|
47
47
|
</style>
|
48
48
|
<div class="message-bottom-sheet" id="messageBottomSheet">
|
@@ -55,7 +55,7 @@ class MessageBottomSheet extends HTMLElement {
|
|
55
55
|
this.messageBottomSheet = this.shadowRoot.getElementById('messageBottomSheet');
|
56
56
|
this.messageContent = this.shadowRoot.getElementById('messageContent');
|
57
57
|
this.closeMessageButton = this.shadowRoot.getElementById('closeMessage');
|
58
|
-
|
58
|
+
this.overlay = this.shadowRoot.getElementById('overlay');
|
59
59
|
|
60
60
|
this.closeMessageButton.onclick = () => this.hideMessage();
|
61
61
|
this.overlay.onclick = () => this.hideMessage();
|
@@ -30,7 +30,7 @@ class OnboardBrandBottomSheet extends HTMLElement {
|
|
30
30
|
bottom: 0;
|
31
31
|
left: 0;
|
32
32
|
right: 0;
|
33
|
-
background-color:
|
33
|
+
background-color: var(--background-color);
|
34
34
|
border-top-left-radius: 14px;
|
35
35
|
border-top-right-radius: 14px;
|
36
36
|
box-shadow: 0 -1.4px 7px rgba(0, 0, 0, 0.1);
|
@@ -71,6 +71,11 @@ class OnboardBrandBottomSheet extends HTMLElement {
|
|
71
71
|
border: 0.7px solid var(--border-color, #E1E4E8);
|
72
72
|
border-radius: 3.5px;
|
73
73
|
font-size: 11.2px;
|
74
|
+
background-color: var(--background-color);
|
75
|
+
<<<<<<< HEAD
|
76
|
+
=======
|
77
|
+
color: var(--text-color);
|
78
|
+
>>>>>>> develop
|
74
79
|
}
|
75
80
|
.tooltip {
|
76
81
|
position: relative;
|
@@ -107,9 +112,10 @@ class OnboardBrandBottomSheet extends HTMLElement {
|
|
107
112
|
cursor: pointer;
|
108
113
|
font-size: 11.2px;
|
109
114
|
transition: background-color 0.3s ease;
|
115
|
+
margin-top: 30px;
|
110
116
|
}
|
111
117
|
.onboard-brand-button:hover {
|
112
|
-
background-color:
|
118
|
+
background-color: var(--hover);
|
113
119
|
}
|
114
120
|
</style>
|
115
121
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css">
|
@@ -117,7 +123,7 @@ class OnboardBrandBottomSheet extends HTMLElement {
|
|
117
123
|
<div>
|
118
124
|
<div class="overlay" id="overlay"></div>
|
119
125
|
<div class="bottom-sheet" id="onboardBrandSheet">
|
120
|
-
<
|
126
|
+
<h2 id="sheetTitle">Onboard New Brand</h2>
|
121
127
|
<form class="onboard-brand-form" id="onboardBrandForm">
|
122
128
|
<div class="form-group">
|
123
129
|
<label for="brandKey">
|
@@ -33,11 +33,7 @@ class EditSectionHandler < BaseHandler
|
|
33
33
|
path = template[:path]
|
34
34
|
|
35
35
|
if File.exist?(path)
|
36
|
-
|
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
|
+
File.write(path, JSON.pretty_generate(data))
|
41
37
|
Solara.logger.debug("Updated Config for #{path}: #{data}")
|
42
38
|
else
|
43
39
|
raise "Config file not found: #{path}"
|
@@ -26,18 +26,6 @@ class OnboardBrandHandler < BaseHandler
|
|
26
26
|
end
|
27
27
|
res.content_type = 'application/json'
|
28
28
|
end
|
29
|
-
|
30
|
-
def onboard_brand(brand_name, brand_key, clone_brand_key = nil)
|
31
|
-
if BrandsManager.instance.exists(brand_key)
|
32
|
-
return { success: false, message: "Brand with key (#{brand_key}) already added!" }
|
33
|
-
end
|
34
|
-
SolaraManager.new.onboard(brand_key, brand_name, clone_brand_key: clone_brand_key, open_dashboard: false)
|
35
|
-
{ success: true, message: "Brand added successfully" }
|
36
|
-
rescue StandardError => e
|
37
|
-
Solara.logger.failure("Error adding brand: #{e.message}")
|
38
|
-
raise
|
39
|
-
end
|
40
|
-
|
41
29
|
end
|
42
30
|
|
43
31
|
def onboard_brand(brand_name, brand_key, clone_brand_key = nil)
|
@@ -46,8 +34,5 @@ class OnboardBrandHandler < BaseHandler
|
|
46
34
|
end
|
47
35
|
SolaraManager.new.onboard(brand_key, brand_name, clone_brand_key: clone_brand_key, open_dashboard: false)
|
48
36
|
{ success: true, message: "Brand added successfully" }
|
49
|
-
rescue StandardError => e
|
50
|
-
Solara.logger.failure("Error adding brand: #{e.message}")
|
51
|
-
raise
|
52
37
|
end
|
53
38
|
end
|
@@ -31,13 +31,6 @@
|
|
31
31
|
"name": {
|
32
32
|
"type": "string"
|
33
33
|
},
|
34
|
-
"inputType": {
|
35
|
-
"type": "string",
|
36
|
-
"enum": [
|
37
|
-
"color",
|
38
|
-
"text"
|
39
|
-
]
|
40
|
-
},
|
41
34
|
"content": {
|
42
35
|
"type": "object",
|
43
36
|
"additionalProperties": {}
|
@@ -46,7 +39,6 @@
|
|
46
39
|
"required": [
|
47
40
|
"key",
|
48
41
|
"name",
|
49
|
-
"inputType",
|
50
42
|
"content"
|
51
43
|
]
|
52
44
|
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
{
|
2
|
+
"type": "object",
|
3
|
+
"properties": {
|
4
|
+
"files": {
|
5
|
+
"type": "array",
|
6
|
+
"items": {
|
7
|
+
"type": "object",
|
8
|
+
"properties": {
|
9
|
+
"source": {
|
10
|
+
"type": "string"
|
11
|
+
},
|
12
|
+
"destination": {
|
13
|
+
"type": "string"
|
14
|
+
},
|
15
|
+
"mandatory": {
|
16
|
+
"type": "boolean"
|
17
|
+
}
|
18
|
+
},
|
19
|
+
"required": [
|
20
|
+
"source",
|
21
|
+
"destination",
|
22
|
+
"mandatory"
|
23
|
+
]
|
24
|
+
}
|
25
|
+
}
|
26
|
+
},
|
27
|
+
"required": [
|
28
|
+
"files"
|
29
|
+
]
|
30
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
{
|
2
|
+
"type": "object",
|
3
|
+
"properties": {
|
4
|
+
"files": {
|
5
|
+
"type": "array",
|
6
|
+
"items": {
|
7
|
+
"type": "object",
|
8
|
+
"properties": {
|
9
|
+
"fileName": {
|
10
|
+
"type": "string"
|
11
|
+
},
|
12
|
+
"generate": {
|
13
|
+
"type": "boolean"
|
14
|
+
},
|
15
|
+
"parentClassName": {
|
16
|
+
"type": "string"
|
17
|
+
},
|
18
|
+
"customClassNames": {
|
19
|
+
"type": "array",
|
20
|
+
"items": {
|
21
|
+
"type": "object",
|
22
|
+
"properties": {
|
23
|
+
"originalName": {
|
24
|
+
"type": "string"
|
25
|
+
},
|
26
|
+
"customName": {
|
27
|
+
"type": "string"
|
28
|
+
}
|
29
|
+
},
|
30
|
+
"required": ["originalName", "customName"]
|
31
|
+
}
|
32
|
+
}
|
33
|
+
},
|
34
|
+
"required": ["fileName", "generate", "parentClassName", "customClassNames"]
|
35
|
+
}
|
36
|
+
}
|
37
|
+
},
|
38
|
+
"required": ["files"]
|
39
|
+
}
|
@@ -25,6 +25,15 @@ structure:
|
|
25
25
|
- type: valid_json
|
26
26
|
- type: json_schema
|
27
27
|
schema_path: platform/android/android_signing.json
|
28
|
+
json:
|
29
|
+
type: directory
|
30
|
+
contents:
|
31
|
+
json_manifest.json:
|
32
|
+
type: file
|
33
|
+
validations:
|
34
|
+
- type: valid_json
|
35
|
+
- type: json_schema
|
36
|
+
schema_path: platform/json_manifest.json
|
28
37
|
ios:
|
29
38
|
type: directory
|
30
39
|
contents:
|
@@ -51,6 +60,15 @@ structure:
|
|
51
60
|
contents:
|
52
61
|
AppIcon.appiconset:
|
53
62
|
type: directory
|
63
|
+
json:
|
64
|
+
type: directory
|
65
|
+
contents:
|
66
|
+
json_manifest.json:
|
67
|
+
type: file
|
68
|
+
validations:
|
69
|
+
- type: valid_json
|
70
|
+
- type: json_schema
|
71
|
+
schema_path: platform/json_manifest.json
|
54
72
|
shared:
|
55
73
|
type: directory
|
56
74
|
contents:
|
@@ -64,6 +82,22 @@ structure:
|
|
64
82
|
type: file
|
65
83
|
validations:
|
66
84
|
- type: valid_json
|
85
|
+
../../global:
|
86
|
+
type: directory
|
87
|
+
contents:
|
88
|
+
resources_manifest.json:
|
89
|
+
type: file
|
90
|
+
validations:
|
91
|
+
- type: valid_json
|
67
92
|
- type: json_schema
|
68
|
-
schema_path: platform/
|
93
|
+
schema_path: platform/global/resources_manifest.json
|
94
|
+
json:
|
95
|
+
type: directory
|
96
|
+
contents:
|
97
|
+
json_manifest.json:
|
98
|
+
type: file
|
99
|
+
validations:
|
100
|
+
- type: valid_json
|
101
|
+
- type: json_schema
|
102
|
+
schema_path: platform/json_manifest.json
|
69
103
|
strict: false
|
@@ -1,4 +1,16 @@
|
|
1
1
|
structure:
|
2
|
+
flutter:
|
3
|
+
type: directory
|
4
|
+
contents:
|
5
|
+
json:
|
6
|
+
type: directory
|
7
|
+
contents:
|
8
|
+
json_manifest.json:
|
9
|
+
type: file
|
10
|
+
validations:
|
11
|
+
- type: valid_json
|
12
|
+
- type: json_schema
|
13
|
+
schema_path: platform/json_manifest.json
|
2
14
|
android:
|
3
15
|
type: directory
|
4
16
|
contents:
|
@@ -64,6 +76,23 @@ structure:
|
|
64
76
|
type: file
|
65
77
|
validations:
|
66
78
|
- type: valid_json
|
79
|
+
|
80
|
+
../../global:
|
81
|
+
type: directory
|
82
|
+
contents:
|
83
|
+
resources_manifest.json:
|
84
|
+
type: file
|
85
|
+
validations:
|
86
|
+
- type: valid_json
|
67
87
|
- type: json_schema
|
68
|
-
schema_path: platform/
|
88
|
+
schema_path: platform/global/resources_manifest.json
|
89
|
+
json:
|
90
|
+
type: directory
|
91
|
+
contents:
|
92
|
+
json_manifest.json:
|
93
|
+
type: file
|
94
|
+
validations:
|
95
|
+
- type: valid_json
|
96
|
+
- type: json_schema
|
97
|
+
schema_path: platform/json_manifest.json
|
69
98
|
strict: false
|
@@ -25,6 +25,15 @@ structure:
|
|
25
25
|
- type: valid_json
|
26
26
|
- type: json_schema
|
27
27
|
schema_path: platform/android/android_signing.json
|
28
|
+
json:
|
29
|
+
type: directory
|
30
|
+
contents:
|
31
|
+
json_manifest.json:
|
32
|
+
type: file
|
33
|
+
validations:
|
34
|
+
- type: valid_json
|
35
|
+
- type: json_schema
|
36
|
+
schema_path: platform/json_manifest.json
|
28
37
|
ios:
|
29
38
|
type: directory
|
30
39
|
contents:
|
@@ -51,6 +60,15 @@ structure:
|
|
51
60
|
contents:
|
52
61
|
AppIcon.appiconset:
|
53
62
|
type: directory
|
63
|
+
json:
|
64
|
+
type: directory
|
65
|
+
contents:
|
66
|
+
json_manifest.json:
|
67
|
+
type: file
|
68
|
+
validations:
|
69
|
+
- type: valid_json
|
70
|
+
- type: json_schema
|
71
|
+
schema_path: platform/json_manifest.json
|
54
72
|
shared:
|
55
73
|
type: directory
|
56
74
|
contents:
|
@@ -64,6 +82,22 @@ structure:
|
|
64
82
|
type: file
|
65
83
|
validations:
|
66
84
|
- type: valid_json
|
85
|
+
../../global:
|
86
|
+
type: directory
|
87
|
+
contents:
|
88
|
+
resources_manifest.json:
|
89
|
+
type: file
|
90
|
+
validations:
|
91
|
+
- type: valid_json
|
67
92
|
- type: json_schema
|
68
|
-
schema_path: platform/
|
93
|
+
schema_path: platform/global/resources_manifest.json
|
94
|
+
json:
|
95
|
+
type: directory
|
96
|
+
contents:
|
97
|
+
json_manifest.json:
|
98
|
+
type: file
|
99
|
+
validations:
|
100
|
+
- type: valid_json
|
101
|
+
- type: json_schema
|
102
|
+
schema_path: platform/json_manifest.json
|
69
103
|
strict: false
|
@@ -29,7 +29,7 @@ class TemplateValidator
|
|
29
29
|
when 'file'
|
30
30
|
validate_file(errors, path, details)
|
31
31
|
else
|
32
|
-
errors << "Unknown type '#{details['type']}' for #{path
|
32
|
+
errors << "Unknown type '#{details['type']}' for #{path}"
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -39,7 +39,7 @@ class TemplateValidator
|
|
39
39
|
|
40
40
|
def validate_directory(errors, path, details)
|
41
41
|
unless path.directory?
|
42
|
-
errors << "Missing directory: #{path
|
42
|
+
errors << "Missing directory: #{path}"
|
43
43
|
return
|
44
44
|
end
|
45
45
|
validate_structure(errors, path, details['contents']) if details['contents']
|
@@ -47,7 +47,7 @@ class TemplateValidator
|
|
47
47
|
|
48
48
|
def validate_file(errors, path, details)
|
49
49
|
unless path.file?
|
50
|
-
errors << "Missing file: #{path
|
50
|
+
errors << "Missing file: #{path}"
|
51
51
|
return
|
52
52
|
end
|
53
53
|
|
@@ -57,12 +57,12 @@ class TemplateValidator
|
|
57
57
|
case validation['type']
|
58
58
|
when 'content_includes'
|
59
59
|
unless content.include?(validation['value'])
|
60
|
-
errors << "File #{path
|
60
|
+
errors << "File #{path} does not contain expected content: #{validation['value']}"
|
61
61
|
end
|
62
62
|
|
63
63
|
when 'content_matches'
|
64
64
|
unless content.match?(Regexp.new(validation['value']))
|
65
|
-
errors << "File #{path
|
65
|
+
errors << "File #{path} does not match expected pattern: #{validation['value']}"
|
66
66
|
end
|
67
67
|
|
68
68
|
when 'file_size'
|
@@ -70,10 +70,10 @@ class TemplateValidator
|
|
70
70
|
min_size = validation['min_size']
|
71
71
|
max_size = validation['max_size']
|
72
72
|
if min_size && size < min_size
|
73
|
-
errors << "File #{path
|
73
|
+
errors << "File #{path} is smaller than expected: #{size} < #{min_size} bytes"
|
74
74
|
end
|
75
75
|
if max_size && size > max_size
|
76
|
-
errors << "File #{path
|
76
|
+
errors << "File #{path} is larger than expected: #{size} > #{max_size} bytes"
|
77
77
|
end
|
78
78
|
|
79
79
|
when 'valid_json'
|
@@ -92,7 +92,7 @@ class TemplateValidator
|
|
92
92
|
end
|
93
93
|
|
94
94
|
else
|
95
|
-
errors << "Unknown validation type '#{validation['type']}' for #{path
|
95
|
+
errors << "Unknown validation type '#{validation['type']}' for #{path}"
|
96
96
|
end
|
97
97
|
end
|
98
98
|
end
|
@@ -101,7 +101,7 @@ class TemplateValidator
|
|
101
101
|
expected_names = expected_structure.keys
|
102
102
|
current_path.children.each do |child|
|
103
103
|
unless expected_names.include?(child.basename.to_s)
|
104
|
-
errors << "Unexpected #{child.directory? ? 'directory' : 'file'}: #{child
|
104
|
+
errors << "Unexpected #{child.directory? ? 'directory' : 'file'}: #{child}"
|
105
105
|
end
|
106
106
|
end
|
107
107
|
end
|