@turbowarp/sb3fix 0.3.1 → 0.3.3
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/README.md +4 -4
- package/package.json +4 -3
- package/src/sb3fix.js +32 -17
package/README.md
CHANGED
|
@@ -40,9 +40,9 @@ const run = async () => {
|
|
|
40
40
|
|
|
41
41
|
// Both sb3fix methods take in an optional options object.
|
|
42
42
|
const options = {
|
|
43
|
-
//
|
|
43
|
+
// While sb3fix runs, it'll log what it's doing and what it fixed. You can monitor those
|
|
44
44
|
// using this callback. These messages are primarily a debugging tool, so the exact output
|
|
45
|
-
// is not
|
|
45
|
+
// is not stable and may change without warning.
|
|
46
46
|
logCallback: (message) => {
|
|
47
47
|
console.log(message);
|
|
48
48
|
}
|
|
@@ -68,10 +68,10 @@ npm ci
|
|
|
68
68
|
Source code is in the src folder. During development do:
|
|
69
69
|
|
|
70
70
|
```bash
|
|
71
|
-
npm
|
|
71
|
+
npm start
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
Then open dist/index.html in your favorite browser.
|
|
74
|
+
Then open dist/index.html in your favorite browser (there isn't a localhost development server).
|
|
75
75
|
|
|
76
76
|
For the final build:
|
|
77
77
|
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@turbowarp/sb3fix",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Fix corrupted Scratch projects",
|
|
5
5
|
"main": "src/sb3fix.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "webpack -c webpack.config.js",
|
|
8
8
|
"watch": "webpack --watch -c webpack.config.js",
|
|
9
|
+
"start": "webpack --watch -c webpack.config.js",
|
|
9
10
|
"update": "node tests/snapshots --update",
|
|
10
11
|
"test": "node tests/snapshots --validate"
|
|
11
12
|
},
|
|
@@ -20,11 +21,11 @@
|
|
|
20
21
|
},
|
|
21
22
|
"homepage": "https://github.com/TurboWarp/sb3fix#readme",
|
|
22
23
|
"dependencies": {
|
|
23
|
-
"@turbowarp/jszip": "^3.11.
|
|
24
|
+
"@turbowarp/jszip": "^3.11.1"
|
|
24
25
|
},
|
|
25
26
|
"devDependencies": {
|
|
26
27
|
"copy-webpack-plugin": "^12.0.2",
|
|
27
|
-
"webpack": "^5.
|
|
28
|
+
"webpack": "^5.96.1",
|
|
28
29
|
"webpack-cli": "^5.1.4"
|
|
29
30
|
}
|
|
30
31
|
}
|
package/src/sb3fix.js
CHANGED
|
@@ -67,7 +67,7 @@ const getKnownExtensions = (project) => {
|
|
|
67
67
|
/**
|
|
68
68
|
* @param {string|object} data project.json as a string or as a parsed object already. If object provided, it will be modified in-place.
|
|
69
69
|
* @param {Options} [options]
|
|
70
|
-
* @returns {object} Fixed project.json object. If
|
|
70
|
+
* @returns {object} Fixed project.json object. If the `data` argument was an object, this will point to the same object.
|
|
71
71
|
*/
|
|
72
72
|
const fixJSON = (data, options = {}) => {
|
|
73
73
|
/**
|
|
@@ -219,8 +219,8 @@ const fixJSON = (data, options = {}) => {
|
|
|
219
219
|
}
|
|
220
220
|
|
|
221
221
|
// https://github.com/scratchfoundation/scratch-parser/blob/665f05d739a202d565a4af70a201909393d456b2/lib/sb3_definitions.json#L51
|
|
222
|
-
const
|
|
223
|
-
if (!
|
|
222
|
+
const knownCostumeFormats = ['png', 'svg', 'jpeg', 'jpg', 'bmp', 'gif'];
|
|
223
|
+
if (!knownCostumeFormats.includes(costume.dataFormat)) {
|
|
224
224
|
if (typeof costume.md5ext === 'string' && costume.md5ext.endsWith('.svg')) {
|
|
225
225
|
log(`costume ${i} is vector, had invalid dataFormat ${costume.dataFormat}`);
|
|
226
226
|
costume.dataFormat = 'svg';
|
|
@@ -261,6 +261,13 @@ const fixJSON = (data, options = {}) => {
|
|
|
261
261
|
throw new Error(`sound ${i} is not an object`);
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
+
// https://github.com/scratchfoundation/scratch-parser/blob/665f05d739a202d565a4af70a201909393d456b2/lib/sb3_definitions.json#L81
|
|
265
|
+
const knownSoundFormats = ['wav', 'wave', 'mp3'];
|
|
266
|
+
if (!knownSoundFormats.includes(sound.dataFormat)) {
|
|
267
|
+
log(`sound ${i} had invalid dataFormat ${sound.dataFormat}`);
|
|
268
|
+
sound.dataFormat = 'mp3';
|
|
269
|
+
}
|
|
270
|
+
|
|
264
271
|
if (typeof sound.name !== 'string') {
|
|
265
272
|
log(`sound ${i} name was not a string`);
|
|
266
273
|
sound.name = String(sound.name);
|
|
@@ -344,11 +351,10 @@ const fixJSON = (data, options = {}) => {
|
|
|
344
351
|
fixTargetInPlace(target);
|
|
345
352
|
}
|
|
346
353
|
|
|
347
|
-
let stage;
|
|
348
354
|
const allStages = targets.filter((target) => target.isStage);
|
|
349
355
|
if (allStages.length === 0) {
|
|
350
356
|
log('stage is missing; adding an empty one');
|
|
351
|
-
|
|
357
|
+
targets.unshift({
|
|
352
358
|
isStage: true,
|
|
353
359
|
name: 'Stage',
|
|
354
360
|
variables: {},
|
|
@@ -373,22 +379,31 @@ const fixJSON = (data, options = {}) => {
|
|
|
373
379
|
videoTransparency: 50,
|
|
374
380
|
videoState: "on",
|
|
375
381
|
textToSpeechLanguage: null
|
|
376
|
-
};
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
const
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
targets.splice(
|
|
382
|
+
});
|
|
383
|
+
} else {
|
|
384
|
+
// We will accept the first stage in targets as the real stage
|
|
385
|
+
const firstStageIndex = targets.findIndex((target) => target.isStage);
|
|
386
|
+
|
|
387
|
+
// Stage must be the first target
|
|
388
|
+
if (firstStageIndex !== 0) {
|
|
389
|
+
log(`stage was at wrong index: ${firstStageIndex}`);
|
|
390
|
+
const stage = targets[firstStageIndex];
|
|
391
|
+
targets.splice(firstStageIndex, 1);
|
|
386
392
|
targets.unshift(stage);
|
|
387
393
|
}
|
|
388
|
-
|
|
389
|
-
|
|
394
|
+
|
|
395
|
+
// Remove all the other stages
|
|
396
|
+
for (let i = targets.length - 1; i > 0; i--) {
|
|
397
|
+
if (targets[i].isStage) {
|
|
398
|
+
log(`removing extra stage at index ${i}`);
|
|
399
|
+
targets.splice(i, 1);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
390
402
|
}
|
|
391
403
|
|
|
404
|
+
// Above checks ensure this invariant holds
|
|
405
|
+
const stage = targets[0];
|
|
406
|
+
|
|
392
407
|
// stage's name must match exactly
|
|
393
408
|
if (stage.name !== 'Stage') {
|
|
394
409
|
log(`stage had wrong name: ${stage.name}`);
|