(retNode)
| 826 | const expectedReturnType = hookType.returnType; |
| 827 | let rootNodeID = null; |
| 828 | const handleRetVal = (retNode) => { |
| 829 | if(isStructType(expectedReturnType)) { |
| 830 | const expectedStructType = structType(expectedReturnType); |
| 831 | if (retNode?.isStrandsNode) { |
| 832 | const returnedNode = getNodeDataFromID(strandsContext.dag, retNode.id); |
| 833 | if (returnedNode.baseType !== expectedStructType.typeName) { |
| 834 | const receivedTypeName = returnedNode.baseType || 'undefined'; |
| 835 | const receivedDim = dag.dimensions[retNode.id]; |
| 836 | const receivedTypeDisplay = receivedDim > 1 ? |
| 837 | `${receivedTypeName}${receivedDim}` : receivedTypeName; |
| 838 | |
| 839 | const expectedProps = expectedStructType.properties |
| 840 | .map(p => p.name).join(', '); |
| 841 | FES.userError('type error', |
| 842 | `You have returned a ${receivedTypeDisplay} from ${hookType.name} when a ${expectedStructType.typeName} was expected.\n\n` + |
| 843 | `The ${expectedStructType.typeName} struct has these properties: { ${expectedProps} }\n\n` + |
| 844 | `Instead of returning a different type, you should modify and return the ${expectedStructType.typeName} struct that was passed to your hook.\n\n` + |
| 845 | `For example:\n` + |
| 846 | `${hookType.name}((inputs) => {\n` + |
| 847 | ` // Modify properties of inputs\n` + |
| 848 | ` inputs.someProperty = ...;\n` + |
| 849 | ` return inputs; // Return the modified struct\n` + |
| 850 | `})` |
| 851 | ); |
| 852 | } |
| 853 | const newDeps = returnedNode.dependsOn.slice(); |
| 854 | for (let i = 0; i < expectedStructType.properties.length; i++) { |
| 855 | const expectedType = expectedStructType.properties[i].dataType; |
| 856 | const receivedNode = createStrandsNode(returnedNode.dependsOn[i], dag.dependsOn[retNode.id], strandsContext); |
| 857 | newDeps[i] = enforceReturnTypeMatch(strandsContext, expectedType, receivedNode, hookType.name); |
| 858 | } |
| 859 | dag.dependsOn[retNode.id] = newDeps; |
| 860 | return retNode.id; |
| 861 | } |
| 862 | else { |
| 863 | const expectedProperties = expectedStructType.properties; |
| 864 | const newStructDependencies = []; |
| 865 | for (let i = 0; i < expectedProperties.length; i++) { |
| 866 | const expectedProp = expectedProperties[i]; |
| 867 | const propName = expectedProp.name; |
| 868 | const receivedValue = retNode[propName]; |
| 869 | if (receivedValue === undefined) { |
| 870 | const expectedProps = expectedReturnType.properties.map(p => p.name).join(', '); |
| 871 | const receivedProps = Object.keys(retNode).join(', '); |
| 872 | FES.userError('type error', |
| 873 | `You've returned an incomplete ${expectedStructType.typeName} struct from ${hookType.name}.\n\n` + |
| 874 | `Expected properties: { ${expectedProps} }\n` + |
| 875 | `Received properties: { ${receivedProps} }\n\n` + |
| 876 | `All properties are required! Make sure to include all properties in the returned struct.` |
| 877 | ); |
| 878 | } |
| 879 | const expectedTypeInfo = expectedProp.dataType; |
| 880 | const returnedPropID = enforceReturnTypeMatch(strandsContext, expectedTypeInfo, receivedValue, hookType.name); |
| 881 | newStructDependencies.push(returnedPropID); |
| 882 | } |
| 883 | const newStruct = build.structConstructorNode(strandsContext, expectedStructType, newStructDependencies); |
| 884 | return newStruct.id; |
| 885 | } |
no test coverage detected