Skip to main content
Glama
field_detector.ts3.64 kB
import { detectFieldType } from '../../api/attribute-types.js'; import { ResourceType } from '../../types/attio.js'; import { convertToBoolean } from '../../utils/attribute-mapping/attribute-mappers.js'; import { CompanyFieldValue, ProcessedFieldValue, } from '../../types/tool-types.js'; import { TypeCache } from './type_cache.js'; export const booleanFieldPatterns = [ 'is_', 'has_', 'can_', 'should_', 'will_', 'was_', 'does_', 'enabled', 'active', 'verified', 'published', 'approved', 'confirmed', 'suspended', 'locked', 'flagged', 'premium', 'featured', 'hidden', 'allow', 'accept', 'available', 'eligible', 'complete', 'valid', ]; export function isBooleanFieldByName(fieldName: string): boolean { const lower = fieldName.toLowerCase(); for (const pattern of booleanFieldPatterns) { if ( lower.startsWith(pattern) || lower.includes('_' + pattern) || lower === pattern || lower.includes(pattern + '_') ) { return true; } } return false; } export async function processFieldValue( fieldName: string, value: CompanyFieldValue ): Promise<ProcessedFieldValue> { if (value === null || value === undefined) { return value as ProcessedFieldValue; } try { let fieldType = TypeCache.getFieldType(fieldName); if (!fieldType) { fieldType = await detectFieldType(ResourceType.COMPANIES, fieldName); TypeCache.setFieldType(fieldName, fieldType); } if ( fieldType === 'boolean' && (typeof value === 'string' || typeof value === 'number') ) { return convertToBoolean(value); } if (fieldType === 'number' && typeof value === 'string') { const numValue = Number(value); if (!isNaN(numValue)) { return numValue; } } if (fieldType === 'array' && typeof value === 'string') { return [value]; } } catch { if ( isBooleanFieldByName(fieldName) && (typeof value === 'string' || typeof value === 'number') ) { try { return convertToBoolean(value); } catch { // swallow errors and fall through to return original value } } // Fallback for number fields based on field name patterns if ( (fieldName.toLowerCase().includes('score') || fieldName.toLowerCase().includes('count') || fieldName.toLowerCase().includes('amount') || fieldName.toLowerCase().includes('revenue') || fieldName.toLowerCase().includes('employees') || fieldName.toLowerCase().includes('funding') || fieldName.toLowerCase().includes('rating')) && typeof value === 'string' ) { const numValue = Number(value); if (!isNaN(numValue)) { return numValue; } } if ( fieldName.toLowerCase().includes('categories') && typeof value === 'string' ) { return [value]; } } // Ensure we return a valid ProcessedFieldValue if ( typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' || value === null || value === undefined ) { return value as ProcessedFieldValue; } // For arrays, ensure all elements are valid types if (Array.isArray(value)) { const processedArray = value.filter( (item) => typeof item === 'string' || typeof item === 'number' || typeof item === 'boolean' ); return processedArray.length > 0 ? processedArray : undefined; } // For other types, convert to string or return undefined return typeof value === 'object' ? String(value) : undefined; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kesslerio/attio-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server