@turbowarp/sb3fix 0.3.3 → 0.3.5
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/package.json +4 -4
- package/src/sb3fix.js +68 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@turbowarp/sb3fix",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"description": "Fix corrupted Scratch projects",
|
|
5
5
|
"main": "src/sb3fix.js",
|
|
6
6
|
"scripts": {
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"@turbowarp/jszip": "^3.11.1"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"copy-webpack-plugin": "^
|
|
28
|
-
"webpack": "^5.
|
|
29
|
-
"webpack-cli": "^
|
|
27
|
+
"copy-webpack-plugin": "^13.0.0",
|
|
28
|
+
"webpack": "^5.98.0",
|
|
29
|
+
"webpack-cli": "^6.0.1"
|
|
30
30
|
}
|
|
31
31
|
}
|
package/src/sb3fix.js
CHANGED
|
@@ -144,6 +144,19 @@ const fixJSON = (data, options = {}) => {
|
|
|
144
144
|
throw new Error('native type is not a number');
|
|
145
145
|
}
|
|
146
146
|
switch (type) {
|
|
147
|
+
// Color: [9, hex color]
|
|
148
|
+
case 9: {
|
|
149
|
+
if (native.length !== 2) {
|
|
150
|
+
throw new Error(`Color native is of unexpected length: ${native.length}`);
|
|
151
|
+
}
|
|
152
|
+
const color = native[1];
|
|
153
|
+
if (typeof color !== 'string' || !/^#[a-f0-9]{6}$/i.test(color)) {
|
|
154
|
+
log('color native had invalid value');
|
|
155
|
+
native[1] = '#000000';
|
|
156
|
+
}
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
|
|
147
160
|
// Variable: [12, variable name, variable id, x?, y?]
|
|
148
161
|
// List: [13, list name, list id, x?, y?]
|
|
149
162
|
// x and y only present if the native is a top-level block
|
|
@@ -199,6 +212,29 @@ const fixJSON = (data, options = {}) => {
|
|
|
199
212
|
}
|
|
200
213
|
};
|
|
201
214
|
|
|
215
|
+
/**
|
|
216
|
+
* @param {string} id
|
|
217
|
+
* @param {unknown} comment
|
|
218
|
+
*/
|
|
219
|
+
const fixCommentInPlace = (id, comment) => {
|
|
220
|
+
if (!isObject(comment)) {
|
|
221
|
+
throw new Error('comment is not an object');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (typeof comment.text !== 'string') {
|
|
225
|
+
throw new Error('comment text is not a string');
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Scratch requires comments to not exceed 8000 characters.
|
|
229
|
+
// We'll store the excess in .extraText so the text won't be truncated if opened in TurboWarp.
|
|
230
|
+
const MAX_LENGTH = 8000;
|
|
231
|
+
if (comment.text.length > MAX_LENGTH) {
|
|
232
|
+
log(`comment ${id} had length ${comment.text.length}`);
|
|
233
|
+
comment.extraText = comment.text.substring(MAX_LENGTH);
|
|
234
|
+
comment.text = comment.text.substring(0, MAX_LENGTH);
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
202
238
|
/**
|
|
203
239
|
* @param {unknown} target
|
|
204
240
|
*/
|
|
@@ -287,6 +323,14 @@ const fixJSON = (data, options = {}) => {
|
|
|
287
323
|
fixBlockInPlace(blockId, block);
|
|
288
324
|
}
|
|
289
325
|
|
|
326
|
+
// Comments are not required
|
|
327
|
+
const comments = target.comments;
|
|
328
|
+
if (comments) {
|
|
329
|
+
for (const [commentId, comment] of Object.entries(comments)) {
|
|
330
|
+
fixCommentInPlace(commentId, comment);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
290
334
|
const variables = target.variables;
|
|
291
335
|
if (!isObject(variables)) {
|
|
292
336
|
throw new Error('variables is not an object');
|
|
@@ -314,6 +358,30 @@ const fixJSON = (data, options = {}) => {
|
|
|
314
358
|
target.layerOrder = 1;
|
|
315
359
|
}
|
|
316
360
|
}
|
|
361
|
+
|
|
362
|
+
const ROTATION_STYLES = [
|
|
363
|
+
'all around',
|
|
364
|
+
'don\'t rotate',
|
|
365
|
+
'left-right'
|
|
366
|
+
];
|
|
367
|
+
if (!target.isStage && !ROTATION_STYLES.includes(target.rotationStyle)) {
|
|
368
|
+
log(`sprite had invalid rotation style ${target.rotationStyle}`);
|
|
369
|
+
target.rotationStyle = 'all around';
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (!target.isStage) {
|
|
373
|
+
const x = target.x;
|
|
374
|
+
if (typeof x !== 'number') {
|
|
375
|
+
log(`target x was ${typeof x}: ${x}`);
|
|
376
|
+
target.x = +x || 0;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
const y = target.y;
|
|
380
|
+
if (typeof y !== 'number') {
|
|
381
|
+
log(`target y was ${typeof y}: ${y}`);
|
|
382
|
+
target.y = +y || 0;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
317
385
|
};
|
|
318
386
|
|
|
319
387
|
/**
|