Skip to content

Commit b808e74

Browse files
committed
feat(schemas): add support for sprite files for 2.0 and 3.0
refactor schemas to support sprite2 and sprite3 files, while reusing rules in common with sb2 and sb3 files BREAKING CHANGE: Change to main API which now takes an additional boolean argument indicating whether a sprite or project is being validated
1 parent 5daad96 commit b808e74

11 files changed

+758
-615
lines changed

index.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,21 @@ var validate = require('./lib/validate');
77
/**
88
* Unpacks, parses, validates, and analyzes Scratch projects. If successful,
99
* will return a valid Scratch project object with appended metadata.
10+
* @param {boolean} isSprite Whether this is a sprite (true) or whole project (false)
1011
* @param {Buffer | string} input Buffer or string representing project
1112
* @param {Function} callback Returns error or project data
1213
*/
13-
module.exports = function (input, callback) {
14+
module.exports = function (isSprite, input, callback) {
1415
// First unpack the input (need this outside of the async waterfall so that
1516
// unpackedProject can be refered to again)
16-
unpack(input, function (err, unpackedProject) {
17+
unpack(isSprite, input, function (err, unpackedProject) {
1718
if (err) return callback(err);
1819

1920
async.waterfall([
2021
function (cb) {
2122
parse(unpackedProject[0], cb);
2223
},
23-
validate
24+
validate.bind(null, isSprite)
2425
], function (error, validatedInput) {
2526
// One more callback wrapper so that we can re-package everything
2627
// with the possible zip returned from unpack

lib/parse.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88
* @return {void}
99
*/
1010
module.exports = function (input, callback) {
11+
var result;
1112
try {
12-
var result = JSON.parse(input);
13-
callback(null, result);
13+
result = JSON.parse(input);
1414
} catch (e) {
1515
return callback(e.toString());
1616
}
17+
return callback(null, result);
1718
};

lib/sb2_definitions.json

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
{
2+
"$id": "https://scratch.mit.edu/sb2_definitions.json",
3+
"$schema": "http://json-schema.org/schema#",
4+
"description": "Scratch 2.0 Project and Sprite Definitions",
5+
"definitions": {
6+
"scripts": {
7+
"type": "array"
8+
},
9+
"sounds": {
10+
"type": "array",
11+
"properties": {
12+
"soundName": {
13+
"type": "string"
14+
},
15+
"soundID": {
16+
"type": "number"
17+
},
18+
"md5": {
19+
"type": "string"
20+
},
21+
"sampleCount": {
22+
"type": "number"
23+
},
24+
"rate": {
25+
"type": "number"
26+
},
27+
"format": {
28+
"type": "string"
29+
}
30+
},
31+
"required": [
32+
"soundName",
33+
"soundID",
34+
"md5",
35+
"sampleCount",
36+
"rate",
37+
"format"
38+
]
39+
},
40+
"costumes": {
41+
"type": "array",
42+
"properties": {
43+
"costumeName": {
44+
"type": "string"
45+
},
46+
"baseLayerID": {
47+
"type": "number"
48+
},
49+
"baseLayerMD5": {
50+
"type": "string"
51+
},
52+
"bitmapResolution": {
53+
"type": "number"
54+
},
55+
"rotationCenterX": {
56+
"type": "number"
57+
},
58+
"rotationCenterY": {
59+
"type": "number"
60+
}
61+
},
62+
"required": [
63+
"costumeName",
64+
"baseLayerID",
65+
"baseLayerMD5",
66+
"bitmapResolution",
67+
"rotationCenterX",
68+
"rotationCenterY"
69+
]
70+
},
71+
"variables": {
72+
"type": "array",
73+
"properties": {
74+
"name": {
75+
"type": "string"
76+
},
77+
"value": {
78+
"type": "string"
79+
},
80+
"isPersistent": {
81+
"type": "boolean"
82+
}
83+
},
84+
"required": [
85+
"name",
86+
"value"
87+
]
88+
},
89+
"sprite_object": {
90+
"type": "object",
91+
"properties": {
92+
"objName": {
93+
"type": "string"
94+
},
95+
"variables": {"$ref": "#/definitions/variables"},
96+
"sounds": {"$ref":"#/definitions/sounds"},
97+
"costumes": {"$ref":"#/definitions/costumes"},
98+
"currentCostumeIndex": {
99+
"type": "number",
100+
"minimum": 0
101+
}
102+
},
103+
"additionalProperties": true,
104+
"required": [
105+
"objName",
106+
"sounds",
107+
"costumes",
108+
"currentCostumeIndex"
109+
]
110+
},
111+
"stage_object" : {
112+
"type": "object",
113+
"properties": {
114+
"objName": {
115+
"type": "string"
116+
},
117+
"variables": {"$ref": "#/definitions/variables"},
118+
"lists": {
119+
"type": "array",
120+
"properties": {
121+
"listName": {
122+
"type": "string"
123+
},
124+
"contents": {
125+
"type": "array"
126+
},
127+
"isPersistent": {
128+
"type": "boolean"
129+
},
130+
"x": {
131+
"type": "number"
132+
},
133+
"y": {
134+
"type": "number"
135+
},
136+
"width": {
137+
"type": "number"
138+
},
139+
"height": {
140+
"type": "number"
141+
},
142+
"visible": {
143+
"type": "boolean"
144+
}
145+
},
146+
"required": [
147+
"listName",
148+
"contents"
149+
]
150+
},
151+
"scripts": {"$ref": "#/definitions/scripts"},
152+
"sounds": {"$ref": "#/definitions/sounds"},
153+
"costumes": {"$ref": "#/definitions/costumes"},
154+
"currentCostumeIndex": {
155+
"type": "number",
156+
"minimum": 0
157+
},
158+
"penLayerMD5": {
159+
"oneOf":[
160+
{"type": "string"},
161+
{"type": "null"}
162+
]
163+
},
164+
"penLayerID": {
165+
"type": "number",
166+
"minimum": -1
167+
},
168+
"tempoBPM": {
169+
"type": "number"
170+
},
171+
"videoAlpha": {
172+
"type": "number",
173+
"minimum": 0,
174+
"maximum": 1
175+
},
176+
"children": {
177+
"type": "array",
178+
"items": {"$ref": "#/definitions/sprite_object"}
179+
}
180+
},
181+
"required": [
182+
"objName",
183+
"costumes",
184+
"currentCostumeIndex",
185+
"penLayerMD5",
186+
"tempoBPM",
187+
"children"
188+
]
189+
}
190+
}
191+
}

0 commit comments

Comments
 (0)