diff --git a/docs/parameterData.json b/docs/parameterData.json index d8a0c9881f..f4bd73d675 100644 --- a/docs/parameterData.json +++ b/docs/parameterData.json @@ -228,6 +228,11 @@ ] ] }, + "isMatrixArray": { + "overloads": [ + [] + ] + }, "fromAxisAngle": { "overloads": [ [ @@ -243,6 +248,13 @@ [] ] }, + "loadingAnimation": { + "overloads": [ + [ + "Function?" + ] + ] + }, "multiply": { "overloads": [ [ @@ -282,13 +294,6 @@ ] ] }, - "rotateBy": { - "overloads": [ - [ - "p5.Quat?" - ] - ] - }, "ellipseMode": { "overloads": [ [ @@ -304,6 +309,13 @@ ] ] }, + "rotateBy": { + "overloads": [ + [ + "p5.Quat?" + ] + ] + }, "nf": { "overloads": [ [ @@ -333,15 +345,6 @@ ] ] }, - "loadImage": { - "overloads": [ - [ - "String|Request", - "function(p5.Image)?", - "function(Event)?" - ] - ] - }, "createVector": { "overloads": [ [ @@ -430,6 +433,15 @@ ] ] }, + "loadImage": { + "overloads": [ + [ + "String|Request", + "function(p5.Image)?", + "function(Event)?" + ] + ] + }, "loadShader": { "overloads": [ [ @@ -454,7 +466,14 @@ "Number?", "Number?", "Number?", - "Object?" + { + "type": "Object", + "optional": 1, + "properties": { + "disableTouchActions": "Boolean?", + "freeRotation": "Boolean?" + } + } ] ] }, @@ -463,13 +482,6 @@ [] ] }, - "beginClip": { - "overloads": [ - [ - "Object?" - ] - ] - }, "ceil": { "overloads": [ [ @@ -500,6 +512,19 @@ ] ] }, + "beginClip": { + "overloads": [ + [ + { + "type": "Object", + "optional": 1, + "properties": { + "invert": "Boolean?" + } + } + ] + ] + }, "selectAll": { "overloads": [ [ @@ -543,11 +568,6 @@ ] ] }, - "endClip": { - "overloads": [ - [] - ] - }, "int": { "overloads": [ [ @@ -588,90 +608,11 @@ [] ] }, - "instanceID": { + "endClip": { "overloads": [ [] ] }, - "smoothstep": { - "overloads": [ - [ - "Number", - "Number", - "Number" - ] - ] - }, - "uniformStorage": { - "overloads": [ - [ - "String", - "p5.StorageBuffer|Function|Object?" - ], - [ - "p5.StorageBuffer|Function|Object?" - ] - ] - }, - "getTexture": { - "overloads": [ - [ - null, - null - ] - ] - }, - "getWorldInputs": { - "overloads": [ - [ - "Function" - ] - ] - }, - "getPixelInputs": { - "overloads": [ - [ - "Function" - ] - ] - }, - "getFinalColor": { - "overloads": [ - [ - "Function" - ] - ] - }, - "getColor": { - "overloads": [ - [ - "Function" - ] - ] - }, - "getObjectInputs": { - "overloads": [ - [ - "Function" - ] - ] - }, - "getCameraInputs": { - "overloads": [ - [ - "Function" - ] - ] - }, - "mix": { - "overloads": [ - [ - "Number|p5.Vector", - "Number|p5.Vector", - "Number|Boolean" - ] - ] - }, "applyMatrix": { "overloads": [ [ @@ -757,15 +698,6 @@ ] ] }, - "resizeCanvas": { - "overloads": [ - [ - "Number", - "Number", - "Boolean?" - ] - ] - }, "saveCanvas": { "overloads": [ [ @@ -779,18 +711,18 @@ ] ] }, - "saveGif": { + "resetMatrix": { "overloads": [ - [ - "String", - "Number", - "Object?" - ] + [] ] }, - "resetMatrix": { + "resizeCanvas": { "overloads": [ - [] + [ + "Number", + "Number", + "Boolean?" + ] ] }, "getItem": { @@ -809,12 +741,18 @@ ] ] }, - "rectMode": { + "arc": { "overloads": [ [ - "CENTER|RADIUS|CORNER|CORNERS" - ], - [] + "Number", + "Number", + "Number", + "Number", + "Number", + "Number", + "CHORD|PIE|OPEN?", + "Integer?" + ] ] }, "month": { @@ -822,6 +760,14 @@ [] ] }, + "rectMode": { + "overloads": [ + [ + "CENTER|RADIUS|CORNER|CORNERS" + ], + [] + ] + }, "random": { "overloads": [ [ @@ -833,34 +779,34 @@ ] ] }, - "loadJSON": { + "saveGif": { "overloads": [ [ - "String|Request", - "Function?", - "Function?" + "String", + "Number", + { + "type": "Object", + "optional": 1, + "properties": { + "delay": "Number?", + "notificationDuration": "Number?", + "notificationID": "String?", + "silent": "Boolean?", + "units": "'seconds'|'frames'?" + } + } ] ] }, - "arc": { + "loadJSON": { "overloads": [ [ - "Number", - "Number", - "Number", - "Number", - "Number", - "Number", - "CHORD|PIE|OPEN?", - "Integer?" + "String|Request", + "Function?", + "Function?" ] ] }, - "noCanvas": { - "overloads": [ - [] - ] - }, "createElement": { "overloads": [ [ @@ -876,6 +822,16 @@ ] ] }, + "cursor": { + "overloads": [ + [ + "ARROW|CROSS|HAND|MOVE|TEXT|WAIT|String", + "Number?", + "Number?" + ], + [] + ] + }, "dist": { "overloads": [ [ @@ -894,13 +850,8 @@ ] ] }, - "cursor": { + "noCanvas": { "overloads": [ - [ - "ARROW|CROSS|HAND|MOVE|TEXT|WAIT|String", - "Number?", - "Number?" - ], [] ] }, @@ -944,50 +895,80 @@ ] ] }, - "set": { + "redraw": { "overloads": [ [ - "Number", - "Number", - "Number|Number[]|Object" + "Integer?" ] ] }, - "loadModel": { + "year": { + "overloads": [ + [] + ] + }, + "transform2D": { "overloads": [ [ - "String|Request", - "String?", - "Boolean?", - "function(p5.Geometry)?", - "function(Event)?" - ], + "...Number?[]" + ] + ] + }, + "transform3D": { + "overloads": [ [ - "String|Request", - "String?", - "function(p5.Geometry)?", - "function(Event)?" - ], + "...Number?[]" + ] + ] + }, + "mat2": { + "overloads": [ [ - "String|Request", - "Boolean", - "function(p5.Geometry)?", - "function(Event)?" - ], + "...Number?[]" + ] + ] + }, + "mat2x2": { + "overloads": [ [ - "String|Request", - "Object?" + "...Number?[]" ] ] }, - "redraw": { + "mat3": { "overloads": [ [ - "Integer?" + "...Number?[]" ] ] }, - "year": { + "mat3x3": { + "overloads": [ + [ + "...Number?[]" + ] + ] + }, + "mat4": { + "overloads": [ + [ + "...Number?[]" + ] + ] + }, + "mat4x4": { + "overloads": [ + [ + "...Number?[]" + ] + ] + }, + "removeElements": { + "overloads": [ + [] + ] + }, + "smooth": { "overloads": [ [] ] @@ -1006,75 +987,142 @@ ] ] }, - "smooth": { + "clearStorage": { "overloads": [ [] ] }, - "clearStorage": { + "beginShape": { + "overloads": [ + [ + "POINTS|LINES|TRIANGLES|TRIANGLE_FAN|TRIANGLE_STRIP|QUADS|QUAD_STRIP|PATH?" + ] + ] + }, + "randomGaussian": { + "overloads": [ + [ + "Number?", + "Number?" + ] + ] + }, + "addElement": { "overloads": [ [] ] }, - "removeElements": { + "instanceID": { "overloads": [ [] ] }, - "beginShape": { + "smoothstep": { "overloads": [ [ - "POINTS|LINES|TRIANGLES|TRIANGLE_FAN|TRIANGLE_STRIP|QUADS|QUAD_STRIP|PATH?" + "Number", + "Number", + "Number" ] ] }, - "saveObj": { + "uniformStorage": { "overloads": [ [ - "String?" + "String", + "p5.StorageBuffer|Function|Object?" + ], + [ + "p5.StorageBuffer|Function|Object?" ] ] }, - "randomGaussian": { + "getTexture": { "overloads": [ [ - "Number?", - "Number?" + null, + null ] ] }, - "addElement": { + "getWorldInputs": { "overloads": [ - [] + [ + "Function" + ] ] }, - "clip": { + "getPixelInputs": { "overloads": [ [ - "Function", - "Object?" + "Function" ] ] }, - "atan": { + "getFinalColor": { "overloads": [ [ - "Number" + "Function" ] ] }, - "createGraphics": { + "getColor": { "overloads": [ [ - "Number", - "Number", - "P2D|WEBGL?", - "HTMLCanvasElement?" - ], + "Function" + ] + ] + }, + "getObjectInputs": { + "overloads": [ + [ + "Function" + ] + ] + }, + "getCameraInputs": { + "overloads": [ + [ + "Function" + ] + ] + }, + "mix": { + "overloads": [ + [ + "Number|p5.Vector", + "Number|p5.Vector", + "Number|Boolean" + ] + ] + }, + "clip": { + "overloads": [ + [ + "Function", + { + "type": "Object", + "optional": 1, + "properties": { + "invert": "Boolean?" + } + } + ] + ] + }, + "set": { + "overloads": [ [ "Number", "Number", - "HTMLCanvasElement?" + "Number|Number[]|Object" + ] + ] + }, + "atan": { + "overloads": [ + [ + "Number" ] ] }, @@ -1100,10 +1148,10 @@ ] ] }, - "exp": { + "saveObj": { "overloads": [ [ - "Number" + "String?" ] ] }, @@ -1115,6 +1163,13 @@ ] ] }, + "exp": { + "overloads": [ + [ + "Number" + ] + ] + }, "specularColor": { "overloads": [ [ @@ -1159,6 +1214,21 @@ ] ] }, + "createGraphics": { + "overloads": [ + [ + "Number", + "Number", + "P2D|WEBGL?", + "HTMLCanvasElement?" + ], + [ + "Number", + "Number", + "HTMLCanvasElement?" + ] + ] + }, "createDiv": { "overloads": [ [ @@ -1185,14 +1255,6 @@ ] ] }, - "rotate": { - "overloads": [ - [ - "Number", - "p5.Vector|Number[]?" - ] - ] - }, "removeItem": { "overloads": [ [ @@ -1211,13 +1273,6 @@ ] ] }, - "setMoveThreshold": { - "overloads": [ - [ - "Number" - ] - ] - }, "ellipse": { "overloads": [ [ @@ -1235,6 +1290,13 @@ ] ] }, + "setMoveThreshold": { + "overloads": [ + [ + "Number" + ] + ] + }, "createP": { "overloads": [ [ @@ -1247,7 +1309,14 @@ [ "String", "String", - "Object?" + { + "type": "Object", + "optional": 1, + "properties": { + "fragment": "Object?", + "vertex": "Object?" + } + } ] ] }, @@ -1292,14 +1361,6 @@ ] ] }, - "saveStl": { - "overloads": [ - [ - "String?", - "Object?" - ] - ] - }, "circle": { "overloads": [ [ @@ -1309,9 +1370,25 @@ ] ] }, - "floor": { + "clear": { "overloads": [ [ + "Number?", + "Number?", + "Number?", + "Number?" + ], + [] + ] + }, + "rotate": { + "overloads": [ + [ + "Number", + "p5.Vector|Number[]?" + ], + [ + null, "Number" ] ] @@ -1321,6 +1398,13 @@ [] ] }, + "floor": { + "overloads": [ + [ + "Number" + ] + ] + }, "loadTable": { "overloads": [ [ @@ -1332,6 +1416,27 @@ ] ] }, + "rotateAxisAngle": { + "overloads": [ + [ + null, + null, + "Number" + ] + ] + }, + "filter": { + "overloads": [ + [ + "THRESHOLD|GRAY|OPAQUE|INVERT|POSTERIZE|BLUR|ERODE|DILATE|BLUR", + "Number?", + "Boolean?" + ], + [ + "p5.Shader" + ] + ] + }, "plane": { "overloads": [ [ @@ -1350,22 +1455,24 @@ [] ] }, - "filter": { + "createSpan": { "overloads": [ [ - "THRESHOLD|GRAY|OPAQUE|INVERT|POSTERIZE|BLUR|ERODE|DILATE|BLUR", - "Number?", - "Boolean?" - ], - [ - "p5.Shader" + "String?" ] ] }, - "createSpan": { + "saveStl": { "overloads": [ [ - "String?" + "String?", + { + "type": "Object", + "optional": 1, + "properties": { + "binary": "Boolean?" + } + } ] ] }, @@ -1378,17 +1485,25 @@ ] ] }, - "rotateX": { - "overloads": [ - [ - "Number" - ] - ] - }, "createFramebuffer": { "overloads": [ [ - "Object?" + { + "type": "Object", + "optional": 1, + "properties": { + "antialias": "Boolean|Number?", + "channels": "RGB|RGBA?", + "density": "Number?", + "depth": "Boolean?", + "depthFormat": "UNSIGNED_INT|FLOAT?", + "format": "UNSIGNED_BYTE|FLOAT|HALF_FLOAT?", + "height": "Number?", + "stencil": "Boolean?", + "textureFiltering": "LINEAR|NEAREST?", + "width": "Number?" + } + } ] ] }, @@ -1406,6 +1521,51 @@ ] ] }, + "loadModel": { + "overloads": [ + [ + "String|Request", + "String?", + "Boolean?", + "function(p5.Geometry)?", + "function(Event)?" + ], + [ + "String|Request", + "String?", + "function(p5.Geometry)?", + "function(Event)?" + ], + [ + "String|Request", + "Boolean", + "function(p5.Geometry)?", + "function(Event)?" + ], + [ + "String|Request", + { + "type": "Object", + "optional": 1, + "properties": { + "failureCallback": "function(Event)?", + "fileType": "String?", + "flipU": "Boolean?", + "flipV": "Boolean?", + "normalize": "Boolean?", + "successCallback": "function(p5.Geometry)?" + } + } + ] + ] + }, + "red": { + "overloads": [ + [ + "p5.Color|Number[]|String" + ] + ] + }, "strokeWeight": { "overloads": [ [ @@ -1414,13 +1574,6 @@ [] ] }, - "red": { - "overloads": [ - [ - "p5.Color|Number[]|String" - ] - ] - }, "cos": { "overloads": [ [ @@ -1443,59 +1596,59 @@ [] ] }, - "background": { + "directionalLight": { "overloads": [ - [ - "p5.Color" - ], - [ - "String", - "Number?" - ], [ "Number", - "Number?" + "Number", + "Number", + "Number", + "Number", + "Number" ], [ "Number", "Number", "Number", - "Number?" + "p5.Vector" ], [ - "Number[]" + "p5.Color|Number[]|String", + "Number", + "Number", + "Number" ], [ - "p5.Image", - "Number?" + "p5.Color|Number[]|String", + "p5.Vector" ] ] }, - "directionalLight": { + "background": { "overloads": [ + [ + "p5.Color" + ], + [ + "String", + "Number?" + ], [ "Number", - "Number", - "Number", - "Number", - "Number", - "Number" + "Number?" ], [ "Number", "Number", "Number", - "p5.Vector" + "Number?" ], [ - "p5.Color|Number[]|String", - "Number", - "Number", - "Number" + "Number[]" ], [ - "p5.Color|Number[]|String", - "p5.Vector" + "p5.Image", + "Number?" ] ] }, @@ -1507,6 +1660,13 @@ ] ] }, + "keyPressed": { + "overloads": [ + [ + "KeyboardEvent?" + ] + ] + }, "lerp": { "overloads": [ [ @@ -1516,10 +1676,11 @@ ] ] }, - "keyPressed": { + "transformPoint": { "overloads": [ [ - "KeyboardEvent?" + null, + null ] ] }, @@ -1534,10 +1695,12 @@ ] ] }, - "clearDepth": { + "createA": { "overloads": [ [ - "Number?" + "String", + "String", + "String?" ] ] }, @@ -1558,15 +1721,6 @@ ] ] }, - "createA": { - "overloads": [ - [ - "String", - "String", - "String?" - ] - ] - }, "saveFrames": { "overloads": [ [ @@ -1596,31 +1750,21 @@ ] ] }, - "clear": { + "clearDepth": { "overloads": [ [ - "Number?", - "Number?", - "Number?", "Number?" - ], - [] - ] - }, - "setup": { - "overloads": [ - [] - ] - }, - "draw": { - "overloads": [ - [] + ] ] }, - "registerAddon": { + "rotateX": { "overloads": [ [ - "Function" + "Number" + ], + [ + null, + "Number" ] ] }, @@ -1634,13 +1778,6 @@ ] ] }, - "rotateY": { - "overloads": [ - [ - "Number" - ] - ] - }, "debugMode": { "overloads": [ [], @@ -1675,13 +1812,6 @@ ] ] }, - "roll": { - "overloads": [ - [ - "Number" - ] - ] - }, "spline": { "overloads": [ [ @@ -1710,6 +1840,29 @@ ] ] }, + "get": { + "overloads": [ + [ + "Number", + "Number", + "Number", + "Number" + ], + [], + [ + "Number", + "Number" + ] + ] + }, + "transformNormal": { + "overloads": [ + [ + null, + null + ] + ] + }, "sin": { "overloads": [ [ @@ -1726,61 +1879,53 @@ ] ] }, - "get": { + "roll": { "overloads": [ [ - "Number", - "Number", - "Number", - "Number" - ], - [], - [ - "Number", "Number" ] ] }, - "log": { + "setup": { "overloads": [ - [ - "Number" - ] + [] ] }, - "shuffle": { + "draw": { + "overloads": [ + [] + ] + }, + "registerAddon": { "overloads": [ [ - "Array", - "Boolean?" + "Function" ] ] }, - "green": { + "log": { "overloads": [ [ - "p5.Color|Number[]|String" + "Number" ] ] }, - "windowResized": { + "green": { "overloads": [ [ - "Event?" + "p5.Color|Number[]|String" ] ] }, - "unchar": { + "shuffle": { "overloads": [ [ - "String" - ], - [ - "String[]" + "Array", + "Boolean?" ] ] }, - "noDebugMode": { + "loadPixels": { "overloads": [ [] ] @@ -1794,7 +1939,17 @@ ] ] }, - "loadPixels": { + "unchar": { + "overloads": [ + [ + "String" + ], + [ + "String[]" + ] + ] + }, + "noDebugMode": { "overloads": [ [] ] @@ -1830,6 +1985,13 @@ ] ] }, + "windowResized": { + "overloads": [ + [ + "Event?" + ] + ] + }, "mag": { "overloads": [ [ @@ -1852,13 +2014,6 @@ ] ] }, - "rotateZ": { - "overloads": [ - [ - "Number" - ] - ] - }, "loadBlob": { "overloads": [ [ @@ -1868,13 +2023,6 @@ ] ] }, - "fullscreen": { - "overloads": [ - [ - "Boolean?" - ] - ] - }, "point": { "overloads": [ [ @@ -1915,6 +2063,13 @@ ] ] }, + "fullscreen": { + "overloads": [ + [ + "Boolean?" + ] + ] + }, "createButton": { "overloads": [ [ @@ -1923,6 +2078,17 @@ ] ] }, + "rotateY": { + "overloads": [ + [ + "Number" + ], + [ + null, + "Number" + ] + ] + }, "createFilterShader": { "overloads": [ [ @@ -1930,21 +2096,21 @@ ] ] }, - "endShape": { + "degrees": { "overloads": [ [ - "CLOSE|OPEN?", - "Integer?" - ], - [ - "Integer" + "Number" ] ] }, - "degrees": { + "endShape": { "overloads": [ [ - "Number" + "CLOSE|OPEN?", + "Integer?" + ], + [ + "Integer" ] ] }, @@ -1983,14 +2149,6 @@ ] ] }, - "pixelDensity": { - "overloads": [ - [ - "Number?" - ], - [] - ] - }, "httpGet": { "overloads": [ [ @@ -2031,22 +2189,25 @@ [] ] }, - "displayDensity": { + "pixelDensity": { "overloads": [ + [ + "Number?" + ], [] ] }, - "radians": { + "keyTyped": { "overloads": [ [ - "Number" + "KeyboardEvent?" ] ] }, - "panorama": { + "radians": { "overloads": [ [ - "p5.Image" + "Number" ] ] }, @@ -2058,10 +2219,10 @@ ] ] }, - "keyTyped": { + "panorama": { "overloads": [ [ - "KeyboardEvent?" + "p5.Image" ] ] }, @@ -2077,16 +2238,9 @@ ] ] }, - "scale": { + "displayDensity": { "overloads": [ - [ - "Number|p5.Vector|Number[]", - "Number?", - "Number?" - ], - [ - "p5.Vector|Number[]" - ] + [] ] }, "unhex": { @@ -2153,11 +2307,6 @@ ] ] }, - "getURL": { - "overloads": [ - [] - ] - }, "max": { "overloads": [ [ @@ -2170,6 +2319,11 @@ ] ] }, + "getURL": { + "overloads": [ + [] + ] + }, "lights": { "overloads": [ [] @@ -2182,11 +2336,6 @@ ] ] }, - "getURLPath": { - "overloads": [ - [] - ] - }, "splineTangent": { "overloads": [ [ @@ -2198,6 +2347,22 @@ ] ] }, + "rotateZ": { + "overloads": [ + [ + "Number" + ], + [ + null, + "Number" + ] + ] + }, + "getURLPath": { + "overloads": [ + [] + ] + }, "normal": { "overloads": [ [ @@ -2210,11 +2375,9 @@ ] ] }, - "shearX": { + "createShape": { "overloads": [ - [ - "Number" - ] + [] ] }, "colorMode": { @@ -2233,34 +2396,16 @@ [] ] }, - "getURLParams": { + "keyIsDown": { "overloads": [ - [] + [ + "Number|String" + ] ] }, - "image": { + "getURLParams": { "overloads": [ - [ - "p5.Image|p5.Element|p5.Texture|p5.Framebuffer|p5.FramebufferTexture|p5.Renderer|p5.Graphics", - "Number", - "Number", - "Number?", - "Number?" - ], - [ - "p5.Image|p5.Element|p5.Texture|p5.Framebuffer|p5.FramebufferTexture", - "Number", - "Number", - "Number", - "Number", - "Number", - "Number", - "Number?", - "Number?", - "CONTAIN|COVER?", - "LEFT|RIGHT|CENTER?", - "TOP|BOTTOM|CENTER?" - ] + [] ] }, "lightFalloff": { @@ -2272,13 +2417,6 @@ ] ] }, - "shader": { - "overloads": [ - [ - "p5.Shader" - ] - ] - }, "mouseMoved": { "overloads": [ [ @@ -2293,10 +2431,10 @@ ] ] }, - "keyIsDown": { + "shader": { "overloads": [ [ - "Number|String" + "p5.Shader" ] ] }, @@ -2307,6 +2445,31 @@ ] ] }, + "image": { + "overloads": [ + [ + "p5.Image|p5.Element|p5.Texture|p5.Framebuffer|p5.FramebufferTexture|p5.Renderer|p5.Graphics", + "Number", + "Number", + "Number?", + "Number?" + ], + [ + "p5.Image|p5.Element|p5.Texture|p5.Framebuffer|p5.FramebufferTexture", + "Number", + "Number", + "Number", + "Number", + "Number", + "Number", + "Number?", + "Number?", + "CONTAIN|COVER?", + "LEFT|RIGHT|CENTER?", + "TOP|BOTTOM|CENTER?" + ] + ] + }, "angleMode": { "overloads": [ [ @@ -2337,13 +2500,6 @@ ] ] }, - "shearY": { - "overloads": [ - [ - "Number" - ] - ] - }, "min": { "overloads": [ [ @@ -2373,18 +2529,17 @@ ] ] }, - "model": { - "overloads": [ - [ - "p5.Geometry", - "Number?" - ] - ] - }, - "hue": { + "buildShape": { "overloads": [ [ - "p5.Color|Number[]|String" + "Function", + { + "type": "Object", + "optional": 1, + "properties": { + "draw": "Boolean?" + } + } ] ] }, @@ -2398,6 +2553,13 @@ ] ] }, + "hue": { + "overloads": [ + [ + "p5.Color|Number[]|String" + ] + ] + }, "cone": { "overloads": [ [ @@ -2418,20 +2580,19 @@ ] ] }, - "worldToScreen": { + "getSVG": { "overloads": [ [ - "Number|p5.Vector", - "Number", - "Number?" + "p5.ShapeCollection" ] ] }, - "vertexProperty": { + "worldToScreen": { "overloads": [ [ - "String", - "Number|Number[]" + "Number|p5.Vector", + "Number", + "Number?" ] ] }, @@ -2448,100 +2609,60 @@ ] ] }, - "screenToWorld": { - "overloads": [ - [ - "Number|p5.Vector", - "Number", - "Number?" - ] - ] - }, - "createModel": { + "vertexProperty": { "overloads": [ [ "String", - "String?", - "Boolean?", - "function(p5.Geometry)?", - "function(Event)?" - ], - [ - "String", - "String?", - "function(p5.Geometry)?", - "function(Event)?" - ], - [ - "String", - "String?", - "Object?" - ] - ] - }, - "strokeShader": { - "overloads": [ - [ - "p5.Shader" - ] - ] - }, - "mousePressed": { - "overloads": [ - [ - "MouseEvent?" - ] - ] - }, - "pow": { - "overloads": [ - [ - "Number", - "Number" + "Number|Number[]" ] ] }, - "translate": { + "screenToWorld": { "overloads": [ [ - "Number", + "Number|p5.Vector", "Number", "Number?" - ], - [ - "p5.Vector" ] ] }, - "tint": { + "scale": { "overloads": [ [ - "Number", - "Number", - "Number", + "Number|p5.Vector|Number[]", + "Number?", "Number?" ], [ - "String" + "p5.Vector|Number[]" ], [ + null, "Number", + "Number?", "Number?" - ], + ] + ] + }, + "mousePressed": { + "overloads": [ [ - "Number[]" - ], + "MouseEvent?" + ] + ] + }, + "strokeShader": { + "overloads": [ [ - "p5.Color" - ], - [] + "p5.Shader" + ] ] }, - "createWriter": { + "pow": { "overloads": [ [ - "String", - "String?" + "Number", + "Number" ] ] }, @@ -2629,6 +2750,14 @@ ] ] }, + "createWriter": { + "overloads": [ + [ + "String", + "String?" + ] + ] + }, "fill": { "overloads": [ [ @@ -2653,18 +2782,6 @@ [] ] }, - "triangle": { - "overloads": [ - [ - "Number", - "Number", - "Number", - "Number", - "Number", - "Number" - ] - ] - }, "text": { "overloads": [ [ @@ -2818,9 +2935,16 @@ [] ] }, - "noTint": { + "triangle": { "overloads": [ - [] + [ + "Number", + "Number", + "Number", + "Number", + "Number", + "Number" + ] ] }, "ellipsoid": { @@ -2834,6 +2958,30 @@ ] ] }, + "tint": { + "overloads": [ + [ + "Number", + "Number", + "Number", + "Number?" + ], + [ + "String" + ], + [ + "Number", + "Number?" + ], + [ + "Number[]" + ], + [ + "p5.Color" + ], + [] + ] + }, "round": { "overloads": [ [ @@ -2859,24 +3007,41 @@ [] ] }, - "imageShader": { + "noTint": { + "overloads": [ + [] + ] + }, + "model": { "overloads": [ [ - "p5.Shader" + "p5.Geometry", + "Number?" ] ] }, - "mouseReleased": { + "shearX": { "overloads": [ [ - "MouseEvent?" + "Number" + ], + [ + null, + "Number" ] ] }, - "write": { + "imageShader": { "overloads": [ [ - "String|Number|Array" + "p5.Shader" + ] + ] + }, + "mouseReleased": { + "overloads": [ + [ + "MouseEvent?" ] ] }, @@ -2896,6 +3061,13 @@ [] ] }, + "write": { + "overloads": [ + [ + "String|Number|Array" + ] + ] + }, "sq": { "overloads": [ [ @@ -2911,20 +3083,18 @@ ] ] }, - "imageMode": { - "overloads": [ - [ - "CORNER|CORNERS|CENTER" - ], - [] - ] - }, "loadFont": { "overloads": [ [ "String", "String?", - "Object?", + { + "type": "Object", + "optional": 1, + "properties": { + "sets": "String|String[]?" + } + }, "Function?", "Function?" ], @@ -2935,6 +3105,38 @@ ] ] }, + "createModel": { + "overloads": [ + [ + "String", + "String?", + "Boolean?", + "function(p5.Geometry)?", + "function(Event)?" + ], + [ + "String", + "String?", + "function(p5.Geometry)?", + "function(Event)?" + ], + [ + "String", + "String?", + { + "type": "Object", + "optional": 1, + "properties": { + "failureCallback": "function(Event)?", + "flipU": "boolean?", + "flipV": "boolean?", + "normalize": "boolean?", + "successCallback": "function(p5.Geometry)?" + } + } + ] + ] + }, "createAudio": { "overloads": [ [ @@ -2953,10 +3155,22 @@ ] ] }, - "sqrt": { + "imageMode": { + "overloads": [ + [ + "CORNER|CORNERS|CENTER" + ], + [] + ] + }, + "shearY": { "overloads": [ [ "Number" + ], + [ + null, + "Number" ] ] }, @@ -2967,6 +3181,13 @@ ] ] }, + "sqrt": { + "overloads": [ + [ + "Number" + ] + ] + }, "close": { "overloads": [ [] @@ -2979,6 +3200,30 @@ ] ] }, + "createSVG": { + "overloads": [ + [ + "String|SVGElement" + ] + ] + }, + "shape": { + "overloads": [ + [ + "p5.ShapeCollection", + "Number?", + "Number?", + { + "type": "Object", + "optional": 1, + "properties": { + "align": "String?", + "scale": "Number|Object?" + } + } + ] + ] + }, "buildMaterialShader": { "overloads": [ [ @@ -3007,6 +3252,22 @@ ] ] }, + "loadSVG": { + "overloads": [ + [ + "String", + "Function?", + "Function?" + ] + ] + }, + "createColorPicker": { + "overloads": [ + [ + "String|p5.Color?" + ] + ] + }, "stroke": { "overloads": [ [ @@ -3031,10 +3292,11 @@ [] ] }, - "createColorPicker": { + "saveSVG": { "overloads": [ [ - "String|p5.Color?" + "p5.ShapeCollection|String?", + "String?" ] ] }, @@ -3099,6 +3361,24 @@ ] ] }, + "translate": { + "overloads": [ + [ + "Number", + "Number", + "Number?" + ], + [ + "p5.Vector" + ], + [ + null, + "Number", + "Number?", + "Number?" + ] + ] + }, "noErase": { "overloads": [ [] @@ -3125,11 +3405,6 @@ ] ] }, - "pop": { - "overloads": [ - [] - ] - }, "mouseWheel": { "overloads": [ [ @@ -3155,7 +3430,14 @@ [ "p5.Color", "p5.Color", - "Object" + { + "type": "Object", + "properties": { + "amount": "number?", + "lerpMode": "RGB|HSB|HSL|RGBP3|HWB|LAB|LCH|OKLAB|OKLCH?", + "outputMode": "RGB|HSB|HSL|RGBP3|HWB|LAB|LCH|OKLAB|OKLCH?" + } + } ] ] }, @@ -3236,15 +3518,12 @@ [] ] }, - "setAttributes": { + "blendMode": { "overloads": [ [ - "String", - "Boolean" + "BLEND|DARKEST|LIGHTEST|DIFFERENCE|MULTIPLY|EXCLUSION|SCREEN|REPLACE|OVERLAY|HARD_LIGHT|SOFT_LIGHT|DODGE|BURN|ADD|REMOVE|SUBTRACT" ], - [ - "Object" - ] + [] ] }, "bezierOrder": { @@ -3255,12 +3534,27 @@ [] ] }, - "blendMode": { + "setAttributes": { "overloads": [ [ - "BLEND|DARKEST|LIGHTEST|DIFFERENCE|MULTIPLY|EXCLUSION|SCREEN|REPLACE|OVERLAY|HARD_LIGHT|SOFT_LIGHT|DODGE|BURN|ADD|REMOVE|SUBTRACT" + "String", + "Boolean" ], - [] + [ + "Object" + ] + ] + }, + "buildStrokeShader": { + "overloads": [ + [ + "Function", + "Object?" + ], + [ + "Object", + "Object?" + ] ] }, "camera": { @@ -3278,36 +3572,29 @@ ] ] }, - "createStorage": { + "pop": { "overloads": [ - [ - "Number|Array|Float32Array|Uint32Array|Int32Array|Object[]" - ] + [] ] }, - "buildStrokeShader": { + "loadStrokeShader": { "overloads": [ [ - "Function", - "Object?" - ], - [ - "Object", - "Object?" + "String", + "Function?", + "Function?" ] ] }, - "baseComputeShader": { + "baseStrokeShader": { "overloads": [ [] ] }, - "loadStrokeShader": { + "createStorage": { "overloads": [ [ - "String", - "Function?", - "Function?" + "Number|Array|Float32Array|Uint32Array|Int32Array|Object[]" ] ] }, @@ -3321,28 +3608,11 @@ ] ] }, - "baseStrokeShader": { - "overloads": [ - [] - ] - }, "resetShader": { "overloads": [ [] ] }, - "buildComputeShader": { - "overloads": [ - [ - "Function", - "Object?" - ], - [ - "Object", - "Object?" - ] - ] - }, "linePerspective": { "overloads": [ [ @@ -3377,18 +3647,19 @@ ] ] }, - "ortho": { + "createStorageList": { "overloads": [ [ - "Number?", - "Number?", - "Number?", - "Number?", - "Number?", - "Number?" + "Number", + "Object|Object[]?" ] ] }, + "baseComputeShader": { + "overloads": [ + [] + ] + }, "texture": { "overloads": [ [ @@ -3396,11 +3667,13 @@ ] ] }, - "compute": { + "ortho": { "overloads": [ [ - "p5.Shader", - "Number", + "Number?", + "Number?", + "Number?", + "Number?", "Number?", "Number?" ] @@ -3413,6 +3686,14 @@ ] ] }, + "normalTexture": { + "overloads": [ + [ + "p5.Image|p5.MediaElement|p5.Graphics|p5.Texture|p5.Framebuffer|p5.FramebufferTexture", + "Number?" + ] + ] + }, "frustum": { "overloads": [ [ @@ -3425,11 +3706,38 @@ ] ] }, + "instances": { + "overloads": [ + [ + "Number|p5.StorageBuffer|p5.StorageList" + ] + ] + }, + "buildComputeShader": { + "overloads": [ + [ + "Function", + "Object?" + ], + [ + "Object", + "Object?" + ] + ] + }, "createCamera": { "overloads": [ [] ] }, + "bumpTexture": { + "overloads": [ + [ + "p5.Image|p5.MediaElement|p5.Graphics|p5.Texture|p5.Framebuffer|p5.FramebufferTexture", + "Number?" + ] + ] + }, "splineProperty": { "overloads": [ [ @@ -3441,18 +3749,17 @@ ] ] }, - "textureMode": { + "setCamera": { "overloads": [ [ - "IMAGE|NORMAL" - ], - [] + "p5.Camera" + ] ] }, - "setCamera": { + "specularTexture": { "overloads": [ [ - "p5.Camera" + "p5.Image|p5.MediaElement|p5.Graphics|p5.Texture|p5.Framebuffer|p5.FramebufferTexture" ] ] }, @@ -3463,16 +3770,28 @@ ] ] }, - "textureWrap": { + "compute": { "overloads": [ [ - "CLAMP|REPEAT|MIRROR", - "CLAMP|REPEAT|MIRROR?" - ], + "p5.Shader", + "Number", + "Number?", + "Number?" + ] + ] + }, + "ambientTexture": { + "overloads": [ [ - "Object" - ], - [] + "p5.Image|p5.MediaElement|p5.Graphics|p5.Texture|p5.Framebuffer|p5.FramebufferTexture" + ] + ] + }, + "shininessTexture": { + "overloads": [ + [ + "p5.Image|p5.MediaElement|p5.Graphics|p5.Texture|p5.Framebuffer|p5.FramebufferTexture" + ] ] }, "vertex": { @@ -3496,8 +3815,11 @@ ] ] }, - "normalMaterial": { + "textureMode": { "overloads": [ + [ + "IMAGE|NORMAL" + ], [] ] }, @@ -3513,6 +3835,23 @@ ] ] }, + "textureWrap": { + "overloads": [ + [ + "CLAMP|REPEAT|MIRROR", + "CLAMP|REPEAT|MIRROR?" + ], + [ + "Object" + ], + [] + ] + }, + "normalMaterial": { + "overloads": [ + [] + ] + }, "ambientMaterial": { "overloads": [ [ @@ -3822,6 +4161,26 @@ ] } }, + "p5.ShapeCollection": { + "begin": { + "overloads": [ + [ + { + "type": "Object", + "optional": 1, + "properties": { + "draw": "Boolean?" + } + } + ] + ] + }, + "end": { + "overloads": [ + [] + ] + } + }, "p5.XML": { "getParent": { "overloads": [ @@ -4168,9 +4527,10 @@ "lerp": { "overloads": [ [ - "Number", - "Number", - "Number", + "...Number[]" + ], + [ + "Number[]", "Number" ], [ @@ -4244,6 +4604,13 @@ ] } }, + "p5.File": { + "revoke": { + "overloads": [ + [] + ] + } + }, "p5.Font": { "textToPaths": { "overloads": [ @@ -4262,7 +4629,14 @@ "String", "Number", "Number", - "Object?" + { + "type": "Object", + "optional": 1, + "properties": { + "sampleFactor": "Number?", + "simplifyThreshold": "Number?" + } + } ] ] }, @@ -4272,7 +4646,14 @@ "String", "Number", "Number", - "Object?" + { + "type": "Object", + "optional": 1, + "properties": { + "sampleFactor": "Number?", + "simplifyThreshold": "Number?" + } + } ] ] }, @@ -4284,7 +4665,14 @@ "Number", "Number", "Number", - "Object?" + { + "type": "Object", + "optional": 1, + "properties": { + "extrude": "Number?", + "sampleFactor": "Number?" + } + } ] ] } @@ -4635,55 +5023,27 @@ ] } }, - "p5.Geometry": { - "calculateBoundingBox": { - "overloads": [ - [] - ] - }, - "clearColors": { - "overloads": [ - [] - ] - }, - "flipU": { - "overloads": [ - [] - ] - }, - "computeFaces": { - "overloads": [ - [] - ] - }, - "computeNormals": { + "p5.StorageList": { + "update": { "overloads": [ [ - "FLAT|SMOOTH?", - "Object?" + "Number[]|Float32Array|Object[]" ] ] }, - "makeEdgesFromFaces": { + "push": { "overloads": [ - [] + [ + "Number|Object" + ] ] }, - "normalize": { + "read": { "overloads": [ [] ] }, - "vertexProperty": { - "overloads": [ - [ - "String", - "Number|Number[]", - "Number?" - ] - ] - }, - "flipV": { + "clear": { "overloads": [ [] ] @@ -4868,6 +5228,66 @@ ] } }, + "p5.Geometry": { + "calculateBoundingBox": { + "overloads": [ + [] + ] + }, + "clearColors": { + "overloads": [ + [] + ] + }, + "flipU": { + "overloads": [ + [] + ] + }, + "computeFaces": { + "overloads": [ + [] + ] + }, + "computeNormals": { + "overloads": [ + [ + "KEEP_CONNECTIONS|SMOOTH|SEGMENTED?", + { + "type": "Object", + "optional": 1, + "properties": { + "roundToPrecision": "Any?" + } + } + ] + ] + }, + "makeEdgesFromFaces": { + "overloads": [ + [] + ] + }, + "normalize": { + "overloads": [ + [] + ] + }, + "vertexProperty": { + "overloads": [ + [ + "String", + "Number|Number[]", + "Number?" + ] + ] + }, + "flipV": { + "overloads": [ + [] + ] + } + }, "p5.Graphics": { "reset": { "overloads": [ @@ -4882,7 +5302,22 @@ "createFramebuffer": { "overloads": [ [ - "Object?" + { + "type": "Object", + "optional": 1, + "properties": { + "antialias": "Boolean|Number?", + "channels": "RGB|RGBA?", + "density": "Number?", + "depth": "Boolean?", + "depthFormat": "UNSIGNED_INT|FLOAT?", + "format": "UNSIGNED_BYTE|FLOAT|HALF_FLOAT?", + "height": "Number?", + "stencil": "Boolean?", + "textureFiltering": "LINEAR|NEAREST?", + "width": "Number?" + } + } ] ] } diff --git a/src/friendly_errors/param_validator.js b/src/friendly_errors/param_validator.js index 8510831344..97c5c2d238 100644 --- a/src/friendly_errors/param_validator.js +++ b/src/friendly_errors/param_validator.js @@ -69,13 +69,21 @@ function validateParams(p5, fn, lifecycles) { // eventually contain both primitive types and web API objects. const schemaMap = { Any: z.any(), + any: z.any(), Array: z.array(z.any()), + array: z.array(z.any()), Boolean: z.boolean(), + boolean: z.boolean(), Function: z.function(), + function: z.function(), Integer: z.number().check(z.int()), + integer: z.number().check(z.int()), Number: z.union([z.number(), z.literal(Infinity), z.literal(-Infinity)]), + number: z.union([z.number(), z.literal(Infinity), z.literal(-Infinity)]), Object: z.object({}), - String: z.string() + object: z.object({}), + String: z.string(), + string: z.string() }; const webAPIObjects = [ @@ -235,6 +243,11 @@ function validateParams(p5, fn, lifecycles) { typeSchema = z.union( types.map(t => generateTypeSchema(t)).filter(s => s !== undefined) ); + } else if ( + (baseType.startsWith("'") && baseType.endsWith("'")) || + (baseType.startsWith('"') && baseType.endsWith('"')) + ) { + typeSchema = z.literal(baseType.slice(1, -1)); } else if (baseType.endsWith('[]')) { typeSchema = z.array(generateTypeSchema(baseType.slice(0, -2))); } else { @@ -246,9 +259,28 @@ function validateParams(p5, fn, lifecycles) { return typeSchema; }; + const isParamOptional = p => + typeof p === 'object' && p !== null + ? Boolean(p.optional) + : Boolean(p?.endsWith('?')); + // Generate a schema for a single parameter. In the case where a parameter can // be of multiple types, `generateTypeSchema` is called for each type. const generateParamSchema = param => { + if (typeof param === 'object' && param !== null) { + const shape = {}; + for (const [propName, propTypeStr] of Object.entries( + param.properties || {} + )) { + shape[propName] = generateParamSchema(propTypeStr).schema; + } + let schema = z.object(shape); + if (param.optional) { + schema = z.optional(schema); + } + return { schema, rest: false }; + } + const isOptional = param?.endsWith('?'); param = param?.replace(/\?$/, ''); @@ -281,12 +313,12 @@ function validateParams(p5, fn, lifecycles) { // combinations that are valid for all numbers of parameters. const generateOverloadCombinations = params => { // No optional parameters, return the original parameter list right away. - if (!params.some(p => p?.endsWith('?'))) { + if (!params.some(isParamOptional)) { return [params]; } const requiredParamsCount = params.filter( - p => p === null || !p.endsWith('?') + p => p === null || !isParamOptional(p) ).length; const result = []; @@ -388,7 +420,24 @@ function validateParams(p5, fn, lifecycles) { const paramSchema = schemaItems[i]; const arg = args[i]; - if (!z.validate(paramSchema, arg)) score++; + if (!z.validate(paramSchema, arg)) { + const isArgObject = + typeof arg === 'object' && arg !== null && !Array.isArray(arg); + const isSchemaObject = + paramSchema.def?.type === 'object' || + (paramSchema.def?.type === 'optional' && + paramSchema.def?.innerType?.def?.type === 'object') || + (z.ZodMiniObject && paramSchema instanceof z.ZodMiniObject) || + (z.ZodMiniOptional && + paramSchema instanceof z.ZodMiniOptional && + paramSchema.def?.innerType instanceof z.ZodMiniObject); + + if (isArgObject && !isSchemaObject) { + score += 3; + } else { + score += 1; + } + } } return score; @@ -431,15 +480,27 @@ function validateParams(p5, fn, lifecycles) { // one by one. let currentError = zodErrorObj.issues[0]; + const argIdx = currentError.path[0]; + const isNested = currentError.path.length > 1; + const propName = isNested ? currentError.path.slice(1).join('.') : null; + const position = + FES.premade.ordinals[argIdx] || + ordinals[argIdx] || + `parameter #${Number(argIdx) + 1}`; + // Helper function to build a type mismatch message. const buildTypeMismatchMessage = ( actualType, expectedTypeStr, - position + pos, + prop ) => { - const positionStr = position - ? FES.log`at the ${ordinals[position]} parameter` - : ''; + let positionStr = ''; + if (prop) { + positionStr = FES.log`for property '${prop}' in the ${pos} parameter`; + } else if (pos) { + positionStr = FES.log`at the ${pos} parameter`; + } const actualTypeStr = actualType ? FES.log`, but received ${actualType}` : ''; @@ -502,12 +563,21 @@ function validateParams(p5, fn, lifecycles) { } const expectedTypesStr = Array.from(expectedTypes).join(' or '); - const position = error.path.join('.'); + const unionArgIdx = error.path[0]; + const unionIsNested = error.path.length > 1; + const unionPropName = unionIsNested + ? error.path.slice(1).join('.') + : null; + const unionPosition = + FES.premade.ordinals[unionArgIdx] || + ordinals[unionArgIdx] || + `parameter #${Number(unionArgIdx) + 1}`; message = FES.log`${message}${buildTypeMismatchMessage( actualType, expectedTypesStr, - position + unionPosition, + unionPropName )} in ${func + '()'}.`; } @@ -536,10 +606,23 @@ function validateParams(p5, fn, lifecycles) { break; } case 'invalid_type': { - const position = FES.premade.ordinals[currentError.path.join('.')]; - const expectedType = FES.premade.types[currentError.expected]; - // NOTE: need type info - message = FES.log`Expected ${expectedType} at the ${position} parameter in ${func + '()'}.`; + const expectedType = + FES.premade.types[currentError.expected] || currentError.expected; + if (isNested) { + message = FES.log`Expected ${expectedType} for property '${propName}' in the ${position} parameter in ${func + '()'}.`; + } else { + message = FES.log`Expected ${expectedType} at the ${position} parameter in ${func + '()'}.`; + } + break; + } + case 'invalid_value': { + const expectedVal = + currentError.values?.join(' or ') || 'valid value'; + if (isNested) { + message = FES.log`Expected ${expectedVal} for property '${propName}' in the ${position} parameter in ${func + '()'}.`; + } else { + message = FES.log`Expected ${expectedVal} at the ${position} parameter in ${func + '()'}.`; + } break; } case 'too_big': { @@ -550,10 +633,13 @@ function validateParams(p5, fn, lifecycles) { break; } case 'custom': { - const position = FES.premade.ordinals[currentError.path.join('.')]; const match = currentError.message.match(/Input not instance of (\w+)/); if (match) { - message = FES.log`Expected ${match[1]} at the ${position} parameter in ${func + '()'}.`; + if (isNested) { + message = FES.log`Expected ${match[1]} for property '${propName}' in the ${position} parameter in ${func + '()'}.`; + } else { + message = FES.log`Expected ${match[1]} at the ${position} parameter in ${func + '()'}.`; + } break; } // Unrecognized custom errors fall through to the default logging below. diff --git a/test/unit/core/param_errors.js b/test/unit/core/param_errors.js index 792835d6ad..5eef675962 100644 --- a/test/unit/core/param_errors.js +++ b/test/unit/core/param_errors.js @@ -49,6 +49,79 @@ suite('Validate Params', function () { assert.isTrue(result.success); }); }); + + suite('validateParams: options object properties (#7752)', function () { + test('loadModel(): valid options object passes', function () { + const result = mockP5Prototype._validate('p5.loadModel', [ + 'model.obj', + { normalize: true, fileType: '.obj' } + ]); + assert.isTrue(result.success); + }); + + test('loadModel(): omitted optional options object passes', function () { + const result = mockP5Prototype._validate('p5.loadModel', [ + 'model.obj' + ]); + assert.isTrue(result.success); + }); + + test('loadModel(): invalid property type targets options overload and names property', function () { + const result = mockP5Prototype._validate('p5.loadModel', [ + 'model.obj', + { normalize: 'NOT_A_BOOLEAN' } + ]); + assert.isFalse(result.success); + assert.include( + result.error.toString(), + "Expected boolean for property 'normalize' in the second parameter" + ); + }); + + test('loadModel(): unlisted extra properties pass without false positives', function () { + const result = mockP5Prototype._validate('p5.loadModel', [ + 'model.obj', + { normalize: true, customVendorFlag: 123 } + ]); + assert.isTrue(result.success); + }); + + test('saveGif(): valid options with string literal union passes', function () { + const result = mockP5Prototype._validate('p5.saveGif', [ + 'sketch', + 5, + { delay: 1, units: 'frames' } + ]); + assert.isTrue(result.success); + }); + + test('saveGif(): invalid string literal in options reports property error', function () { + const result = mockP5Prototype._validate('p5.saveGif', [ + 'sketch', + 5, + { units: 'hours' } + ]); + assert.isFalse(result.success); + assert.include( + result.error.toString(), + "property 'units'" + ); + }); + + test('orbitControl(): invalid option property type reports property error', function () { + const result = mockP5Prototype._validate('p5.orbitControl', [ + 1, + 2, + 3, + { disableTouchActions: 'NOT_A_BOOLEAN' } + ]); + assert.isFalse(result.success); + assert.include( + result.error.toString(), + "property 'disableTouchActions'" + ); + }); + }); suite( 'validateParams: multiple types allowed for single parameter', function () { diff --git a/utils/convert.mjs b/utils/convert.mjs index 2e3219caf3..85b9a00418 100644 --- a/utils/convert.mjs +++ b/utils/convert.mjs @@ -46,7 +46,10 @@ const htmlStrategy = { processDescription: desc => descriptionString(desc), - processType: type => typeObject(type) + processType: (type, param) => ({ + ...typeObject(type), + ...(param?.properties?.length ? { properties: param.properties } : {}) + }) }; const processed = processData(data, htmlStrategy); @@ -117,12 +120,13 @@ for (const key in constUsage) { function cleanUpClassItems(data) { for (const classItem in data) { - if (typeof data[classItem] === 'object') { + if (typeof data[classItem] === 'object' && data[classItem] !== null) { if (data[classItem].overloads) { delete data[classItem].name; delete data[classItem].class; + } else { + cleanUpClassItems(data[classItem]); } - cleanUpClassItems(data[classItem]); } } @@ -142,6 +146,30 @@ function cleanUpClassItems(data) { // optional parameters, we'll add a ? to the end of parameter type to // indicate that it's optional. const processParam = param => { + if (param.properties && param.properties.length > 0) { + const rawProps = {}; + for (const prop of param.properties) { + const propName = prop.name.replace(/^.*\./, ''); + const propTypeObj = typeObject(prop.type); + let typeStr = propTypeObj.type || 'Any'; + if ((propTypeObj.optional || prop.optional || prop.default !== undefined) && !typeStr.endsWith('?')) { + typeStr += '?'; + } + rawProps[propName] = typeStr; + } + + const sortedProperties = {}; + for (const key of Object.keys(rawProps).sort()) { + sortedProperties[key] = rawProps[key]; + } + + return { + type: 'Object', + optional: param.optional ? 1 : undefined, + properties: sortedProperties + }; + } + let type = param.type; if (param.optional) { type += '?'; @@ -184,7 +212,7 @@ function cleanUpClassItems(data) { }; for (const classItem in data) { - if (typeof data[classItem] === 'object') { + if (typeof data[classItem] === 'object' && data[classItem] !== null) { data[classItem] = flattenOverloads(data[classItem]); } } diff --git a/utils/shared-helpers.mjs b/utils/shared-helpers.mjs index b13d2b26f6..fe794d7378 100644 --- a/utils/shared-helpers.mjs +++ b/utils/shared-helpers.mjs @@ -133,6 +133,10 @@ export function typeObject(node) { }; } else if (node.type === 'RestType') { return { type: typeObject(node.expression).type, rest: true }; + } else if (node.type === 'StringLiteralType') { + return { type: `'${node.value}'` }; + } else if (node.type === 'NumericLiteralType') { + return { type: `${node.value}` }; } else { // TODO // - handle record types