@keymanapp/kmc-package 17.0.155-alpha → 17.0.157-alpha
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.
- package/build/src/compiler/cp1252.d.ts +10 -0
- package/build/src/compiler/cp1252.d.ts.map +1 -0
- package/build/src/compiler/cp1252.js +289 -0
- package/build/src/compiler/cp1252.js.map +1 -0
- package/build/src/compiler/kmp-compiler.d.ts +28 -25
- package/build/src/compiler/kmp-compiler.d.ts.map +1 -1
- package/build/src/compiler/kmp-compiler.js +333 -265
- package/build/src/compiler/kmp-compiler.js.map +1 -1
- package/build/src/compiler/kmp-inf-writer.d.ts +24 -0
- package/build/src/compiler/kmp-inf-writer.d.ts.map +1 -0
- package/build/src/compiler/kmp-inf-writer.js +145 -0
- package/build/src/compiler/kmp-inf-writer.js.map +1 -0
- package/build/src/compiler/kmx-keyboard-metadata.d.ts +6 -0
- package/build/src/compiler/kmx-keyboard-metadata.d.ts.map +1 -0
- package/build/src/compiler/kmx-keyboard-metadata.js +18 -0
- package/build/src/compiler/kmx-keyboard-metadata.js.map +1 -0
- package/build/src/compiler/messages.d.ts +114 -114
- package/build/src/compiler/messages.d.ts.map +1 -1
- package/build/src/compiler/messages.js +70 -67
- package/build/src/compiler/messages.js.map +1 -1
- package/build/src/compiler/package-keyboard-target-validator.d.ts +15 -0
- package/build/src/compiler/package-keyboard-target-validator.d.ts.map +1 -0
- package/build/src/compiler/package-keyboard-target-validator.js +36 -0
- package/build/src/compiler/package-keyboard-target-validator.js.map +1 -0
- package/build/src/compiler/package-metadata-collector.d.ts +19 -0
- package/build/src/compiler/package-metadata-collector.d.ts.map +1 -0
- package/build/src/compiler/package-metadata-collector.js +78 -0
- package/build/src/compiler/package-metadata-collector.js.map +1 -0
- package/build/src/compiler/package-metadata-updater.d.ts +7 -0
- package/build/src/compiler/package-metadata-updater.d.ts.map +1 -0
- package/build/src/compiler/package-metadata-updater.js +13 -0
- package/build/src/compiler/package-metadata-updater.js.map +1 -0
- package/build/src/compiler/package-validation.d.ts +18 -15
- package/build/src/compiler/package-validation.d.ts.map +1 -1
- package/build/src/compiler/package-validation.js +162 -152
- package/build/src/compiler/package-validation.js.map +1 -1
- package/build/src/compiler/package-version-validator.d.ts +23 -0
- package/build/src/compiler/package-version-validator.d.ts.map +1 -0
- package/build/src/compiler/package-version-validator.js +92 -0
- package/build/src/compiler/package-version-validator.js.map +1 -0
- package/build/src/compiler/redist-files.d.ts +20 -18
- package/build/src/compiler/redist-files.d.ts.map +1 -1
- package/build/src/compiler/redist-files.js +59 -57
- package/build/src/compiler/redist-files.js.map +1 -1
- package/build/src/compiler/web-keyboard-metadata.d.ts +22 -0
- package/build/src/compiler/web-keyboard-metadata.d.ts.map +1 -0
- package/build/src/compiler/web-keyboard-metadata.js +34 -0
- package/build/src/compiler/web-keyboard-metadata.js.map +1 -0
- package/build/src/main.d.ts +5 -3
- package/build/src/main.d.ts.map +1 -1
- package/build/src/main.js +5 -3
- package/build/src/main.js.map +1 -1
- package/package.json +7 -8
- package/build/src/compiler/keyman-targets.d.ts +0 -18
- package/build/src/compiler/keyman-targets.d.ts.map +0 -1
- package/build/src/compiler/keyman-targets.js +0 -53
- package/build/src/compiler/keyman-targets.js.map +0 -1
- package/build/src/compiler/package-version-validation.d.ts +0 -24
- package/build/src/compiler/package-version-validation.d.ts.map +0 -1
- package/build/src/compiler/package-version-validation.js +0 -153
- package/build/src/compiler/package-version-validation.js.map +0 -1
|
@@ -1,265 +1,333 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
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
|
-
|
|
260
|
-
data
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
1
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="149aa499-2354-5472-a58b-4584cba7a5fe")}catch(e){}}();
|
|
2
|
+
import * as xml2js from 'xml2js';
|
|
3
|
+
import JSZip from 'jszip';
|
|
4
|
+
import KEYMAN_VERSION from "@keymanapp/keyman-version";
|
|
5
|
+
import { KeymanFileTypes, KvkFile } from '@keymanapp/common-types';
|
|
6
|
+
import { CompilerMessages } from './messages.js';
|
|
7
|
+
import { PackageMetadataCollector } from './package-metadata-collector.js';
|
|
8
|
+
import { KmpInfWriter } from './kmp-inf-writer.js';
|
|
9
|
+
import { transcodeToCP1252 } from './cp1252.js';
|
|
10
|
+
import { MIN_LM_FILEVERSION_KMP_JSON, PackageVersionValidator } from './package-version-validator.js';
|
|
11
|
+
import { PackageKeyboardTargetValidator } from './package-keyboard-target-validator.js';
|
|
12
|
+
import { PackageMetadataUpdater } from './package-metadata-updater.js';
|
|
13
|
+
const KMP_JSON_FILENAME = 'kmp.json';
|
|
14
|
+
const KMP_INF_FILENAME = 'kmp.inf';
|
|
15
|
+
export class KmpCompiler {
|
|
16
|
+
callbacks;
|
|
17
|
+
constructor(callbacks) {
|
|
18
|
+
this.callbacks = callbacks;
|
|
19
|
+
}
|
|
20
|
+
transformKpsToKmpObject(kpsFilename) {
|
|
21
|
+
// Load the KPS data from XML as JS structured data.
|
|
22
|
+
const buffer = this.callbacks.loadFile(kpsFilename);
|
|
23
|
+
if (!buffer) {
|
|
24
|
+
this.callbacks.reportMessage(CompilerMessages.Error_FileDoesNotExist({ filename: kpsFilename }));
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const data = new TextDecoder().decode(buffer);
|
|
28
|
+
const kpsPackage = (() => {
|
|
29
|
+
let a;
|
|
30
|
+
let parser = new xml2js.Parser({
|
|
31
|
+
tagNameProcessors: [xml2js.processors.firstCharLowerCase],
|
|
32
|
+
explicitArray: false
|
|
33
|
+
});
|
|
34
|
+
// TODO: add unit test for xml errors parsing .kps file
|
|
35
|
+
parser.parseString(data, (e, r) => { if (e)
|
|
36
|
+
throw e; a = r; });
|
|
37
|
+
return a;
|
|
38
|
+
})();
|
|
39
|
+
let kps = kpsPackage.package;
|
|
40
|
+
//
|
|
41
|
+
// To convert to kmp.json, we need to:
|
|
42
|
+
//
|
|
43
|
+
// 1. Unwrap arrays (and convert to array where single object)
|
|
44
|
+
// 2. Fix casing on `iD`
|
|
45
|
+
// 3. Rewrap info, keyboard.languages, lexicalModel.languages, startMenu.items elements
|
|
46
|
+
// 4. Remove options.followKeyboardVersion, file.fileType
|
|
47
|
+
// 5. Convert file.copyLocation to a Number
|
|
48
|
+
// 6. Filenames need to be basenames (but this comes after processing)
|
|
49
|
+
//
|
|
50
|
+
// Start to construct the kmp.json file from the .kps file
|
|
51
|
+
let kmp = {
|
|
52
|
+
system: {
|
|
53
|
+
fileVersion: null,
|
|
54
|
+
keymanDeveloperVersion: KEYMAN_VERSION.VERSION
|
|
55
|
+
},
|
|
56
|
+
options: {}
|
|
57
|
+
};
|
|
58
|
+
//
|
|
59
|
+
// Fill in additional fields
|
|
60
|
+
//
|
|
61
|
+
let keys = [
|
|
62
|
+
['executeProgram', 'executeProgram'],
|
|
63
|
+
['graphicFile', 'graphicFile'],
|
|
64
|
+
['msiFileName', 'msiFilename'],
|
|
65
|
+
['msiOptions', 'msiOptions'],
|
|
66
|
+
['readMeFile', 'readmeFile']
|
|
67
|
+
];
|
|
68
|
+
if (kps.options) {
|
|
69
|
+
for (let [src, dst] of keys) {
|
|
70
|
+
if (kps.options[src]) {
|
|
71
|
+
if (dst == 'graphicFile' || dst == 'readmeFile') {
|
|
72
|
+
kmp.options[dst] = /[/\\]?([^/\\]*)$/.exec(kps.options[src])[1];
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
kmp.options[dst] = kps.options[src];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//
|
|
81
|
+
// Add basic metadata
|
|
82
|
+
//
|
|
83
|
+
if (kps.info) {
|
|
84
|
+
kmp.info = this.kpsInfoToKmpInfo(kps.info);
|
|
85
|
+
}
|
|
86
|
+
//
|
|
87
|
+
// Add file metadata
|
|
88
|
+
//
|
|
89
|
+
if (kps.files && kps.files.file) {
|
|
90
|
+
kmp.files = this.arrayWrap(kps.files.file).map((file) => {
|
|
91
|
+
return {
|
|
92
|
+
name: file.name.trim(),
|
|
93
|
+
description: file.description.trim(),
|
|
94
|
+
copyLocation: parseInt(file.copyLocation, 10) || undefined
|
|
95
|
+
// note: we don't emit fileType as that is not permitted in kmp.json
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
kmp.files = kmp.files ?? [];
|
|
100
|
+
// Keyboard packages also include a legacy kmp.inf file (this will be removed,
|
|
101
|
+
// one day)
|
|
102
|
+
if (kps.keyboards && kps.keyboards.keyboard) {
|
|
103
|
+
kmp.files.push({
|
|
104
|
+
name: KMP_INF_FILENAME,
|
|
105
|
+
description: "Package information"
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
// Add the standard kmp.json self-referential to match existing implementations
|
|
109
|
+
kmp.files.push({
|
|
110
|
+
name: KMP_JSON_FILENAME,
|
|
111
|
+
description: "Package information (JSON)"
|
|
112
|
+
});
|
|
113
|
+
//
|
|
114
|
+
// Add keyboard metadata
|
|
115
|
+
//
|
|
116
|
+
if (kps.keyboards && kps.keyboards.keyboard) {
|
|
117
|
+
kmp.keyboards = this.arrayWrap(kps.keyboards.keyboard).map((keyboard) => ({
|
|
118
|
+
displayFont: keyboard.displayFont ? this.callbacks.path.basename(keyboard.displayFont) : undefined,
|
|
119
|
+
oskFont: keyboard.oSKFont ? this.callbacks.path.basename(keyboard.oSKFont) : undefined,
|
|
120
|
+
name: keyboard.name.trim(),
|
|
121
|
+
id: keyboard.iD.trim(),
|
|
122
|
+
version: keyboard.version.trim(),
|
|
123
|
+
rtl: keyboard.rTL == 'True' ? true : undefined,
|
|
124
|
+
languages: keyboard.languages ?
|
|
125
|
+
this.kpsLanguagesToKmpLanguages(this.arrayWrap(keyboard.languages.language)) :
|
|
126
|
+
[]
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
//
|
|
130
|
+
// Add lexical-model metadata
|
|
131
|
+
//
|
|
132
|
+
if (kps.lexicalModels && kps.lexicalModels.lexicalModel) {
|
|
133
|
+
kmp.lexicalModels = this.arrayWrap(kps.lexicalModels.lexicalModel).map((model) => ({
|
|
134
|
+
name: model.name.trim(),
|
|
135
|
+
id: model.iD.trim(),
|
|
136
|
+
languages: model.languages ?
|
|
137
|
+
this.kpsLanguagesToKmpLanguages(this.arrayWrap(model.languages.language)) : []
|
|
138
|
+
}));
|
|
139
|
+
}
|
|
140
|
+
//
|
|
141
|
+
// Collect metadata from keyboards (and later models) in order to update
|
|
142
|
+
// the kmp.json metadata for use downstream in apps. This will also be
|
|
143
|
+
// used later to fill in .keyboard_info file data.
|
|
144
|
+
//
|
|
145
|
+
const collector = new PackageMetadataCollector(this.callbacks);
|
|
146
|
+
const metadata = collector.collectKeyboardMetadata(kpsFilename, kmp);
|
|
147
|
+
if (metadata == null) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
//
|
|
151
|
+
// Verify keyboard versions and update version metadata where appropriate
|
|
152
|
+
//
|
|
153
|
+
const versionValidator = new PackageVersionValidator(this.callbacks);
|
|
154
|
+
if (!versionValidator.validateAndUpdateVersions(kps, kmp, metadata)) {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
if (kps.keyboards && kps.keyboards.keyboard) {
|
|
158
|
+
kmp.system.fileVersion = versionValidator.getMinKeymanVersion(metadata);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
kmp.system.fileVersion = MIN_LM_FILEVERSION_KMP_JSON;
|
|
162
|
+
}
|
|
163
|
+
//
|
|
164
|
+
// Verify that packages that target mobile devices include a .js file
|
|
165
|
+
//
|
|
166
|
+
const targetValidator = new PackageKeyboardTargetValidator(this.callbacks);
|
|
167
|
+
targetValidator.verifyAllTargets(kmp, metadata);
|
|
168
|
+
//
|
|
169
|
+
// Update assorted keyboard metadata from the keyboards in the package
|
|
170
|
+
//
|
|
171
|
+
const updater = new PackageMetadataUpdater();
|
|
172
|
+
updater.updatePackage(metadata);
|
|
173
|
+
//
|
|
174
|
+
// Add Windows Start Menu metadata
|
|
175
|
+
//
|
|
176
|
+
if (kps.startMenu && (kps.startMenu.folder || kps.startMenu.items)) {
|
|
177
|
+
kmp.startMenu = {};
|
|
178
|
+
if (kps.startMenu.addUninstallEntry === '')
|
|
179
|
+
kmp.startMenu.addUninstallEntry = true;
|
|
180
|
+
if (kps.startMenu.folder)
|
|
181
|
+
kmp.startMenu.folder = kps.startMenu.folder;
|
|
182
|
+
if (kps.startMenu.items && kps.startMenu.items.item) {
|
|
183
|
+
kmp.startMenu.items = this.arrayWrap(kps.startMenu.items.item);
|
|
184
|
+
// Remove default values
|
|
185
|
+
for (let item of kmp.startMenu.items) {
|
|
186
|
+
if (item.icon == '')
|
|
187
|
+
delete item.icon;
|
|
188
|
+
if (item.location == 'psmelStartMenu')
|
|
189
|
+
delete item.location;
|
|
190
|
+
if (item.arguments == '')
|
|
191
|
+
delete item.arguments;
|
|
192
|
+
// Horrific case change between .kps and kmp.json:
|
|
193
|
+
item.filename = item.fileName;
|
|
194
|
+
delete item.fileName;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
kmp.startMenu.items = [];
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
kmp = this.stripUndefined(kmp);
|
|
202
|
+
return kmp;
|
|
203
|
+
}
|
|
204
|
+
// Helper functions
|
|
205
|
+
kpsInfoToKmpInfo(info) {
|
|
206
|
+
let ni = {};
|
|
207
|
+
const keys = [
|
|
208
|
+
['author', 'author'],
|
|
209
|
+
['copyright', 'copyright'],
|
|
210
|
+
['name', 'name'],
|
|
211
|
+
['version', 'version'],
|
|
212
|
+
['webSite', 'website']
|
|
213
|
+
];
|
|
214
|
+
for (let [src, dst] of keys) {
|
|
215
|
+
if (info[src]) {
|
|
216
|
+
ni[dst] = { description: info[src]._ ?? (typeof info[src] == 'string' ? info[src].toString() : '') };
|
|
217
|
+
if (info[src].$ && info[src].$.URL)
|
|
218
|
+
ni[dst].url = info[src].$.URL;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return ni;
|
|
222
|
+
}
|
|
223
|
+
;
|
|
224
|
+
arrayWrap(a) {
|
|
225
|
+
if (Array.isArray(a)) {
|
|
226
|
+
return a;
|
|
227
|
+
}
|
|
228
|
+
return [a];
|
|
229
|
+
}
|
|
230
|
+
;
|
|
231
|
+
kpsLanguagesToKmpLanguages(language) {
|
|
232
|
+
if (language.length == 0 || language[0] == undefined) {
|
|
233
|
+
return [];
|
|
234
|
+
}
|
|
235
|
+
return language.map((element) => { return { name: element._, id: element.$.ID }; });
|
|
236
|
+
}
|
|
237
|
+
;
|
|
238
|
+
stripUndefined(o) {
|
|
239
|
+
for (const key in o) {
|
|
240
|
+
if (o[key] === undefined) {
|
|
241
|
+
delete o[key];
|
|
242
|
+
}
|
|
243
|
+
else if (typeof o[key] == 'object') {
|
|
244
|
+
o[key] = this.stripUndefined(o[key]);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return o;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Returns a Promise to the serialized data which can then be written to a .kmp file.
|
|
251
|
+
*
|
|
252
|
+
* @param kpsFilename - Filename of the kps, not read, used only for calculating relative paths
|
|
253
|
+
* @param kmpJsonData - The kmp.json Object
|
|
254
|
+
*/
|
|
255
|
+
buildKmpFile(kpsFilename, kmpJsonData) {
|
|
256
|
+
const zip = JSZip();
|
|
257
|
+
// Make a copy of kmpJsonData, as we mutate paths for writing
|
|
258
|
+
const data = JSON.parse(JSON.stringify(kmpJsonData));
|
|
259
|
+
if (!data.files) {
|
|
260
|
+
data.files = [];
|
|
261
|
+
}
|
|
262
|
+
const hasKmpInf = !!data.files.find(file => file.name == KMP_INF_FILENAME);
|
|
263
|
+
let failed = false;
|
|
264
|
+
data.files.forEach((value) => {
|
|
265
|
+
// Get the path of the file
|
|
266
|
+
let filename = value.name;
|
|
267
|
+
// We add this separately after zipping all other files
|
|
268
|
+
if (filename == KMP_JSON_FILENAME || filename == KMP_INF_FILENAME) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
if (this.callbacks.path.isAbsolute(filename)) {
|
|
272
|
+
// absolute paths are not portable to other computers
|
|
273
|
+
this.callbacks.reportMessage(CompilerMessages.Warn_AbsolutePath({ filename: filename }));
|
|
274
|
+
}
|
|
275
|
+
filename = this.callbacks.resolveFilename(kpsFilename, filename);
|
|
276
|
+
const basename = this.callbacks.path.basename(filename);
|
|
277
|
+
if (!this.callbacks.fs.existsSync(filename)) {
|
|
278
|
+
this.callbacks.reportMessage(CompilerMessages.Error_FileDoesNotExist({ filename: filename }));
|
|
279
|
+
failed = true;
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
let memberFileData;
|
|
283
|
+
try {
|
|
284
|
+
memberFileData = this.callbacks.loadFile(filename);
|
|
285
|
+
}
|
|
286
|
+
catch (e) {
|
|
287
|
+
this.callbacks.reportMessage(CompilerMessages.Error_FileCouldNotBeRead({ filename: filename, e: e }));
|
|
288
|
+
failed = true;
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
this.warnIfKvkFileIsNotBinary(filename, memberFileData);
|
|
292
|
+
zip.file(basename, memberFileData);
|
|
293
|
+
// Remove path data from files before JSON save
|
|
294
|
+
value.name = basename;
|
|
295
|
+
});
|
|
296
|
+
if (failed) {
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
zip.file(KMP_JSON_FILENAME, JSON.stringify(data, null, 2));
|
|
300
|
+
if (hasKmpInf) {
|
|
301
|
+
zip.file(KMP_INF_FILENAME, this.buildKmpInf(data));
|
|
302
|
+
}
|
|
303
|
+
// Generate kmp file
|
|
304
|
+
return zip.generateAsync({ type: 'binarystring', compression: 'DEFLATE' });
|
|
305
|
+
}
|
|
306
|
+
buildKmpInf(data) {
|
|
307
|
+
const writer = new KmpInfWriter(data);
|
|
308
|
+
const s = writer.write();
|
|
309
|
+
return transcodeToCP1252(s);
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Legacy .kmp compiler would transform xml-format .kvk files into a binary .kvk file; now
|
|
313
|
+
* we want that to remain the responsibility of the keyboard compiler, so we'll warn the
|
|
314
|
+
* few users who are still doing this
|
|
315
|
+
*/
|
|
316
|
+
warnIfKvkFileIsNotBinary(filename, data) {
|
|
317
|
+
if (!KeymanFileTypes.filenameIs(filename, ".kvk" /* KeymanFileTypes.Binary.VisualKeyboard */)) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
if (data.byteLength < 4) {
|
|
321
|
+
// TODO: Not a valid .kvk file; should we be reporting this?
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
if (data[0] != KvkFile.KVK_HEADER_IDENTIFIER_BYTES[0] ||
|
|
325
|
+
data[1] != KvkFile.KVK_HEADER_IDENTIFIER_BYTES[1] ||
|
|
326
|
+
data[2] != KvkFile.KVK_HEADER_IDENTIFIER_BYTES[2] ||
|
|
327
|
+
data[3] != KvkFile.KVK_HEADER_IDENTIFIER_BYTES[3]) {
|
|
328
|
+
this.callbacks.reportMessage(CompilerMessages.Warn_FileIsNotABinaryKvkFile({ filename: filename }));
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
//# debugId=149aa499-2354-5472-a58b-4584cba7a5fe
|
|
333
|
+
//# sourceMappingURL=kmp-compiler.js.map
|