Skip to main content
Glama
verifyIdenticObjectFormat.ts3.82 kB
type FlatType = string | number | boolean | object | null | undefined; type RecursiveType = | FlatType | { [key: string]: RecursiveType } | Array<RecursiveType>; type VerifyIdenticObjectFormatResult = { isIdentic: boolean; error?: string; }; /** * Verifies that two objects have identical structure (same keys, array lengths, and types) * but not necessarily the same values. * Useful for validating translations maintain the same format as the original. * * @param object - The object to verify * @param expectedFormat - The expected format to compare against * @param path - Current path in the object tree (for error messages) * @returns true if structures match, throws error with details if they don't */ export const verifyIdenticObjectFormat = ( object: RecursiveType, expectedFormat: RecursiveType, path: string = 'root' ): VerifyIdenticObjectFormatResult => { // Check if both are null or undefined if (expectedFormat === null || expectedFormat === undefined) { if (expectedFormat !== object) { return { isIdentic: false, error: `Type mismatch at ${path}: expected ${expectedFormat === null ? 'null' : 'undefined'}, got ${object === null ? 'null' : typeof object}`, }; } return { isIdentic: true, }; } // Get the type of both values const expectedType = Array.isArray(expectedFormat) ? 'array' : typeof expectedFormat; const objectType = Array.isArray(object) ? 'array' : typeof object; // Check if types match if (expectedType !== objectType) { return { isIdentic: false, error: `Type mismatch at ${path}: expected ${expectedType}, got ${objectType}`, }; } // Handle arrays if (Array.isArray(expectedFormat) && Array.isArray(object)) { if (expectedFormat.length !== object.length) { return { isIdentic: false, error: `Array length mismatch at ${path}: expected ${expectedFormat.length} elements, got ${object.length}`, }; } // Recursively check each element for (let i = 0; i < expectedFormat.length; i++) { const result = verifyIdenticObjectFormat( object[i], expectedFormat[i], `${path}[${i}]` ); if (!result.isIdentic) { return result; } } return { isIdentic: true, }; } // Handle objects (excluding null and arrays) if ( typeof expectedFormat === 'object' && typeof object === 'object' && expectedFormat !== null && object !== null ) { const expectedKeys = Object.keys(expectedFormat); const objectKeys = Object.keys(object); // Check if number of keys match if (expectedKeys.length !== objectKeys.length) { return { isIdentic: false, error: `Object keys count mismatch at ${path}: expected ${expectedKeys.length} keys, got ${objectKeys.length}`, }; } // Check if keys match and are in the same order for (let i = 0; i < expectedKeys.length; i++) { if (expectedKeys[i] !== objectKeys[i]) { return { isIdentic: false, error: `Object keys mismatch at ${path}: expected key "${expectedKeys[i]}" at position ${i}, got "${objectKeys[i]}"`, }; } } // Recursively check each property for (const key of expectedKeys) { const result = verifyIdenticObjectFormat( (object as Record<string, RecursiveType>)[key], (expectedFormat as Record<string, RecursiveType>)[key], `${path}.${key}` ); if (!result.isIdentic) { return result; } } return { isIdentic: true, }; } // For primitive types (string, number, boolean), just verify they're the same type // We don't check the actual values as per requirements return { isIdentic: true, }; };

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/aymericzip/intlayer'

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