1import React from 'react'; 2 3import MonoText from '../MonoText'; 4import { EnumParameter, FunctionArgument, FunctionParameter, ObjectParameter } from './index.types'; 5import { isCurrentPlatformSupported } from './utils'; 6 7export default function FunctionSignature({ 8 namespace, 9 name, 10 parameters, 11 args, 12}: { 13 namespace: string; 14 name: string; 15 parameters: FunctionParameter[]; 16 args: FunctionArgument[]; 17}) { 18 const renderArguments = () => { 19 return parameters 20 .map((parameter, idx) => { 21 if (!isCurrentPlatformSupported(parameter.platforms)) { 22 return; 23 } 24 switch (parameter.type) { 25 case 'object': 26 return convertObjectArgumentToString(args[idx], parameter); 27 case 'enum': 28 return convertEnumArgumentToString(args[idx], parameter); 29 case 'constant': 30 return parameter.name; 31 default: 32 return String(args[idx]); 33 } 34 }) 35 .filter((arg) => !!arg) // filter out all void values 36 .join(', '); 37 }; 38 39 return ( 40 <MonoText> 41 {namespace}.{name}({renderArguments()}) 42 </MonoText> 43 ); 44} 45 46function convertObjectArgumentToString(arg: FunctionArgument, parameter: ObjectParameter) { 47 const properties = parameter.properties 48 .map((property) => { 49 // skip object properties unsupported on the current platform 50 if (!isCurrentPlatformSupported(property.platforms)) { 51 return; 52 } 53 54 if (typeof arg !== 'object' || Array.isArray(arg) /** filter out tuples/arrays */) { 55 throw new Error( 56 `Value ${arg} is not an object. Expecting object for ${parameter.name} argument` 57 ); 58 } 59 60 if (!(property.name in arg)) { 61 throw new Error( 62 `Property ${ 63 property.name 64 } is missing in argument. Available parameter properties: ${parameter.properties 65 .map((p) => p.name) 66 .join(', ')} and argument properties: ${Object.keys(arg).join(', ')}` 67 ); 68 } 69 70 const value = arg[property.name]; 71 72 // skip `undefined` values 73 if (value === undefined) { 74 return; 75 } 76 77 if (property.type === 'enum') { 78 return `${property.name}: ${convertEnumArgumentToString(value, property)}`; 79 } 80 81 return `${property.name}: ${property.type === 'string' ? `"${value}"` : value}`; 82 }) 83 .filter((entry) => !!entry) // filter out all void values 84 .join(',\n '); 85 86 return `{\n ${properties}\n}`; 87} 88 89function convertEnumArgumentToString(arg: FunctionArgument, { name, values }: EnumParameter) { 90 // this should always find the current value for the enum, if failed something is messed up somewhere else 91 // eslint-disable-next-line no-case-declarations 92 const value = values.find(({ value }) => value === arg); 93 if (!value) { 94 throw new Error( 95 `Value ${arg} not found in available values for enum parameter ${name}. Available values: ${values 96 .map((v) => `{${v.name} -> ${v.value}`) 97 .join(', ')}` 98 ); 99 } 100 return value.name; 101} 102