1f94354caSBartłomiej Bukowskiimport React from 'react'; 2f94354caSBartłomiej Bukowski 3f94354caSBartłomiej Bukowskiimport { EnumParameter, FunctionArgument, FunctionParameter, ObjectParameter } from './index.types'; 4f94354caSBartłomiej Bukowskiimport { isCurrentPlatformSupported } from './utils'; 5*8a424bebSJames Ideimport MonoText from '../MonoText'; 6f94354caSBartłomiej Bukowski 70111d1deSBartłomiej Bukowskiexport default function FunctionSignature(props: { 80111d1deSBartłomiej Bukowski namespace: string; 90111d1deSBartłomiej Bukowski name: string; 100111d1deSBartłomiej Bukowski parameters: FunctionParameter[]; 110111d1deSBartłomiej Bukowski args: FunctionArgument[]; 120111d1deSBartłomiej Bukowski}) { 130111d1deSBartłomiej Bukowski return <MonoText>{generateFunctionSignature(props)}</MonoText>; 140111d1deSBartłomiej Bukowski} 150111d1deSBartłomiej Bukowski 160111d1deSBartłomiej Bukowskiexport function generateFunctionSignature({ 17f94354caSBartłomiej Bukowski namespace, 18f94354caSBartłomiej Bukowski name, 19f94354caSBartłomiej Bukowski parameters, 20f94354caSBartłomiej Bukowski args, 21f94354caSBartłomiej Bukowski}: { 22f94354caSBartłomiej Bukowski namespace: string; 23f94354caSBartłomiej Bukowski name: string; 24f94354caSBartłomiej Bukowski parameters: FunctionParameter[]; 25f94354caSBartłomiej Bukowski args: FunctionArgument[]; 26f94354caSBartłomiej Bukowski}) { 270111d1deSBartłomiej Bukowski return `${namespace}.${name}(${argumentsToString(args, parameters)})`; 280111d1deSBartłomiej Bukowski} 290111d1deSBartłomiej Bukowski 300111d1deSBartłomiej Bukowskifunction argumentsToString(args: FunctionArgument[], parameters: FunctionParameter[]) { 31f94354caSBartłomiej Bukowski return parameters 32f94354caSBartłomiej Bukowski .map((parameter, idx) => { 33f94354caSBartłomiej Bukowski if (!isCurrentPlatformSupported(parameter.platforms)) { 34f94354caSBartłomiej Bukowski return; 35f94354caSBartłomiej Bukowski } 36f94354caSBartłomiej Bukowski switch (parameter.type) { 37f94354caSBartłomiej Bukowski case 'object': 38f94354caSBartłomiej Bukowski return convertObjectArgumentToString(args[idx], parameter); 39f94354caSBartłomiej Bukowski case 'enum': 40f94354caSBartłomiej Bukowski return convertEnumArgumentToString(args[idx], parameter); 41f94354caSBartłomiej Bukowski case 'constant': 42f94354caSBartłomiej Bukowski return parameter.name; 43f94354caSBartłomiej Bukowski default: 44f94354caSBartłomiej Bukowski return String(args[idx]); 45f94354caSBartłomiej Bukowski } 46f94354caSBartłomiej Bukowski }) 47f94354caSBartłomiej Bukowski .filter((arg) => !!arg) // filter out all void values 48f94354caSBartłomiej Bukowski .join(', '); 49f94354caSBartłomiej Bukowski} 50f94354caSBartłomiej Bukowski 51f94354caSBartłomiej Bukowskifunction convertObjectArgumentToString(arg: FunctionArgument, parameter: ObjectParameter) { 52f94354caSBartłomiej Bukowski const properties = parameter.properties 53f94354caSBartłomiej Bukowski .map((property) => { 54f94354caSBartłomiej Bukowski // skip object properties unsupported on the current platform 55f94354caSBartłomiej Bukowski if (!isCurrentPlatformSupported(property.platforms)) { 56f94354caSBartłomiej Bukowski return; 57f94354caSBartłomiej Bukowski } 58f94354caSBartłomiej Bukowski 59f94354caSBartłomiej Bukowski if (typeof arg !== 'object' || Array.isArray(arg) /** filter out tuples/arrays */) { 60f94354caSBartłomiej Bukowski throw new Error( 61f94354caSBartłomiej Bukowski `Value ${arg} is not an object. Expecting object for ${parameter.name} argument` 62f94354caSBartłomiej Bukowski ); 63f94354caSBartłomiej Bukowski } 64f94354caSBartłomiej Bukowski 65f94354caSBartłomiej Bukowski if (!(property.name in arg)) { 66f94354caSBartłomiej Bukowski throw new Error( 67f94354caSBartłomiej Bukowski `Property ${ 68f94354caSBartłomiej Bukowski property.name 69f94354caSBartłomiej Bukowski } is missing in argument. Available parameter properties: ${parameter.properties 70f94354caSBartłomiej Bukowski .map((p) => p.name) 71f94354caSBartłomiej Bukowski .join(', ')} and argument properties: ${Object.keys(arg).join(', ')}` 72f94354caSBartłomiej Bukowski ); 73f94354caSBartłomiej Bukowski } 74f94354caSBartłomiej Bukowski 75f94354caSBartłomiej Bukowski const value = arg[property.name]; 76f94354caSBartłomiej Bukowski 77f94354caSBartłomiej Bukowski // skip `undefined` values 78f94354caSBartłomiej Bukowski if (value === undefined) { 79f94354caSBartłomiej Bukowski return; 80f94354caSBartłomiej Bukowski } 81f94354caSBartłomiej Bukowski 82f94354caSBartłomiej Bukowski if (property.type === 'enum') { 838974afb9Saleqsio const stringArgument = convertEnumArgumentToString(value, property); 848974afb9Saleqsio if (!stringArgument) return; 858974afb9Saleqsio return `${property.name}: ${stringArgument}`; 86f94354caSBartłomiej Bukowski } 87f94354caSBartłomiej Bukowski 88f94354caSBartłomiej Bukowski return `${property.name}: ${property.type === 'string' ? `"${value}"` : value}`; 89f94354caSBartłomiej Bukowski }) 90f94354caSBartłomiej Bukowski .filter((entry) => !!entry) // filter out all void values 91f94354caSBartłomiej Bukowski .join(',\n '); 92f94354caSBartłomiej Bukowski 93f94354caSBartłomiej Bukowski return `{\n ${properties}\n}`; 94f94354caSBartłomiej Bukowski} 95f94354caSBartłomiej Bukowski 96f94354caSBartłomiej Bukowskifunction convertEnumArgumentToString(arg: FunctionArgument, { name, values }: EnumParameter) { 97f94354caSBartłomiej Bukowski // this should always find the current value for the enum, if failed something is messed up somewhere else 98f94354caSBartłomiej Bukowski // eslint-disable-next-line no-case-declarations 990111d1deSBartłomiej Bukowski const value = values.find(({ value }) => 1000111d1deSBartłomiej Bukowski typeof value === 'object' && typeof arg === 'object' 1010111d1deSBartłomiej Bukowski ? JSON.stringify(value) === JSON.stringify(arg) // for tuple case 1020111d1deSBartłomiej Bukowski : value === arg 1030111d1deSBartłomiej Bukowski ); 104f94354caSBartłomiej Bukowski if (!value) { 1058974afb9Saleqsio return; 106f94354caSBartłomiej Bukowski } 107f94354caSBartłomiej Bukowski return value.name; 108f94354caSBartłomiej Bukowski} 109