-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathtojson.js
259 lines (243 loc) · 9.29 KB
/
tojson.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
// Copyright 2020 Raising the Floor - International
//
// Licensed under the New BSD license. You may not use this file except in
// compliance with this License.
//
// You may obtain a copy of the License at
// https://github.com/GPII/universal/blob/master/LICENSE.txt
//
// The R&D leading to these results received funding from the:
// * Rehabilitation Services Administration, US Dept. of Education under
// grant H421A150006 (APCP)
// * National Institute on Disability, Independent Living, and
// Rehabilitation Research (NIDILRR)
// * Administration for Independent Living & Dept. of Education under grants
// H133E080022 (RERC-IT) and H133E130028/90RE5003-01-00 (UIITA-RERC)
// * European Union's Seventh Framework Programme (FP7/2007-2013) grant
// agreement nos. 289016 (Cloud4all) and 610510 (Prosperity4All)
// * William and Flora Hewlett Foundation
// * Ontario Ministry of Research and Innovation
// * Canadian Foundation for Innovation
// * Adobe Foundation
// * Consumer Electronics Association Foundation
var yaml = require('yaml');
var fs = require('fs');
var input = process.argv[2];
if (!input){
process.stderr.write("Usage: node tojson.js <registry>.yaml\n");
process.exit(-1);
}
var HandlerTypes = {
client: "org.raisingthefloor.morphic.client"
};
function addInfoToClientHandlers(solutions){
for (var solutionIndex = 0, solutionCount = solutions.length; solutionIndex < solutionCount; ++solutionIndex){
var solution = solutions[solutionIndex];
for (var settingIndex = 0, settingCount = solution.settings.length; settingIndex < settingCount; ++settingIndex){
var setting = solution.settings[settingIndex];
if (setting.handler.type == HandlerTypes.client){
setting.handler.solution = solution.id;
setting.handler.preference = setting.name;
}
}
}
}
function verifySolutions(solutions){
var ids = new Set();
for (var i = 0, l = solutions.length; i < l; ++i){
var solution = solutions[i];
if (!solution.id){
throw new Error("Missing solution id for solution index " + i);
}
if (ids.has(solution.id)){
throw new Error("Duplicate solution id " + solution.id);
}
ids.add(solution.id);
verifySolution(solution);
}
}
function verifySolution(solution){
if (!solution.settings){
throw new Error("Missing settings for solution " + solution.id);
}
var names = new Set();
for (var i = 0, l = solution.settings.length; i < l; ++i){
var setting = solution.settings[i];
if (!setting.name){
throw new Error("Missing setting name for " + solution.id + " setting index " + i);
}
if (names.has(setting.name)){
throw new Error("Duplicate setting name " + solution.id + "." + setting.name);
}
names.add(setting.name);
verifySetting(solution, setting);
}
}
function verifySetting(solution, setting){
var key = solution.id + "." + setting.name;
if (!allowedSettingTypes.has(setting.type)){
throw new Error("Invalid type (" + setting.type + ") for " + key);
}
if (setting.default === undefined){
throw new Error("Missing default for " + key);
}
if (!setting.handler){
throw new Error("Missing setting handler for " + key);
}
verifyHandler(solution, setting, setting.handler);
if (setting.finalizer){
verifyFinalizer(solution, setting, setting.finalizer);
}
}
var allowedSettingTypes = new Set([
"string",
"integer",
"double",
"boolean",
"files"
]);
function verifyHandler(solution, setting, handler){
var key = solution.id + "." + setting.name;
var verifier = handlerVerifiers[handler.type];
if (!verifier){
throw new Error("Invalid handler type (" + handler.type + ") for " + key);
}
verifier(solution, setting, handler);
}
var handlerVerifiers = {
"org.raisingthefloor.morphic.client": function(solution, setting, handler){
},
"com.microsoft.windows.registry": function(solution, setting, handler){
var key = solution.id + "." + setting.name;
if (!handler.key_name){
throw new Error("Missing registry key name for " + key);
}
if (!handler.value_name){
throw new Error("Missing registry value name for " + key);
}
if (!handler.value_type){
throw new Error("Missing registry value type for " + key);
}
var allowedSettingTypes = registryValueTypeMap[handler.value_type];
if (allowedSettingTypes === undefined){
throw new Error("Invalid registry value type (" + handler.value_type + ") for " + key);
}
if (!allowedSettingTypes.has(setting.type)){
throw new Error("Incompatible setting and registry types for " + key);
}
},
"com.microsoft.windows.system": function(solution, setting, handler){
var key = solution.id + "." + setting.name;
if (!handler.setting_id){
throw new Error("Missing system setting id for " + key);
}
if (!handler.value_type){
throw new Error("Missing system setting value type for " + key);
}
var allowedSettingTypes = systemValueTypeMap[handler.value_type];
if (allowedSettingTypes === undefined){
throw new Error("Invalid system setting value type (" + handler.value_type + ") for " + key);
}
if (!allowedSettingTypes.has(setting.type)){
throw new Error("Incompatible setting and system types for " + key);
}
if (setting.type == "integer" && handler.value_type == "string"){
if (!handler.integer_map){
throw new Error("Integer map is required for " + key);
}
}
},
"com.microsoft.windows.ini": function(solution, setting, handler){
var key = solution.id + "." + setting.name;
if (!handler.filename){
throw new Error("Missing ini filename name for " + key);
}
if (!handler.section){
throw new Error("Missing ini section for " + key);
}
if (!handler.key){
throw new Error("Missing ini key name for " + key);
}
},
"com.microsoft.windows.files": function(solution, setting, handler){
var key = solution.id + "." + setting.name;
if (!handler.root){
throw new Error("Missing root folder for " + key);
}
if (!handler.files){
throw new Error("Missing files list for " + key);
}
if (setting.type != "files"){
throw new Error("Files handler can only be used on settings of type 'files', at " + key);
}
},
"com.microsoft.windows.process": function(solution, setting, handler){
var key = solution.id + "." + setting.name;
if (!handler.exe){
throw new Error("Missing exe name for " + key);
}
if (!handler.state){
throw new Error("Missing process state name for " + key);
}
if (handler.state != "running" && handler.state != "installed"){
throw new Error("Process state must be one of (running, installed) for " + key);
}
if (setting.type != "boolean"){
throw new Error("Process handler can only be used for boolean settings, at " + key);
}
}
};
function verifyFinalizer(solution, setting, finalizer){
var key = solution.id + "." + setting.name;
var verifier = finalizerVerifiers[finalizer.type];
if (!verifier){
throw new Error("Invalid finalizer type (" + finalizer.type + ") for " + key);
}
verifier(solution, setting, finalizer);
}
var finalizerVerifiers = {
"com.microsoft.windows.spi": function(solution, setting, finalizer){
if (!finalizer.action){
throw new Error("Missing finalizer action for " + key);
}
if (!spiActions.has(finalizer.action)){
throw new Error("Invalid finalizer action for " + key);
}
},
"com.microsoft.windows.process": function(solution, setting, finalizer){
var key = solution.id + "." + setting.name;
if (!finalizer.exe){
throw new Error("Missing finalizer exe name for " + key);
}
if (!finalizer.action){
throw new Error("Missing finalizer process action name for " + key);
}
if (finalizer.action != "start" && finalizer.action != "stop" && finalizer.action != "restart"){
throw new Error("Finalizer process action must be one of (start, stop, restart) for " + key);
}
}
};
var registryValueTypeMap = {
"string": new Set(["string"]),
"expandString": new Set(["string"]),
"dword": new Set(["integer", "boolean"]),
"qword": new Set(["integer"])
};
var systemValueTypeMap = {
"string": new Set(["string", "integer"]),
"boolean": new Set(["boolean"]),
"integer": new Set(["integer"]),
"idPrefixedEnum": new Set(["integer"])
};
var spiActions = new Set(["setcursors"])
fs.readFile(input, 'utf-8', function(err, contents){
if (err){
console.error(err);
return;
}
var root = yaml.parse(contents);
verifySolutions(root.solutions);
addInfoToClientHandlers(root.solutions);
process.stdout.write(JSON.stringify(root.solutions, null, 2));
process.stdout.write("\n");
});