@intlayer/chokidar
Version:
Uses chokidar to scan and build Intlayer declaration files into dictionaries based on Intlayer configuration.
1 lines • 6.14 kB
Source Map (JSON)
{"version":3,"file":"verifyIdenticObjectFormat.cjs","names":[],"sources":["../../../src/utils/verifyIdenticObjectFormat.ts"],"sourcesContent":["type FlatType = string | number | boolean | object | null | undefined;\n\ntype RecursiveType =\n | FlatType\n | { [key: string]: RecursiveType }\n | Array<RecursiveType>;\n\ntype VerifyIdenticObjectFormatResult = {\n isIdentic: boolean;\n error?: string;\n};\n\n/**\n * Verifies that two objects have identical structure (same keys, array lengths, and types)\n * but not necessarily the same values.\n * Useful for validating translations maintain the same format as the original.\n *\n * @param object - The object to verify\n * @param expectedFormat - The expected format to compare against\n * @param path - Current path in the object tree (for error messages)\n * @returns true if structures match, throws error with details if they don't\n */\nexport const verifyIdenticObjectFormat = (\n object: RecursiveType,\n expectedFormat: RecursiveType,\n path: string = 'root'\n): VerifyIdenticObjectFormatResult => {\n // Check if both are null or undefined\n if (expectedFormat === null || expectedFormat === undefined) {\n if (expectedFormat !== object) {\n return {\n isIdentic: false,\n error: `Type mismatch at ${path}: expected ${expectedFormat === null ? 'null' : 'undefined'}, got ${object === null ? 'null' : typeof object}`,\n };\n }\n return {\n isIdentic: true,\n };\n }\n\n // Allow null/undefined returns from AI for any expected primitive type\n // (AI may return null for content it cannot translate)\n if (\n (object === null || object === undefined) &&\n typeof expectedFormat !== 'object' &&\n !Array.isArray(expectedFormat)\n ) {\n return { isIdentic: true };\n }\n\n // Get the type of both values\n const expectedType = Array.isArray(expectedFormat)\n ? 'array'\n : typeof expectedFormat;\n const objectType = Array.isArray(object) ? 'array' : typeof object;\n\n // Check if types match\n if (expectedType !== objectType) {\n return {\n isIdentic: false,\n error: `Type mismatch at ${path}: expected ${expectedType}, got ${objectType}`,\n };\n }\n\n // Handle arrays\n if (Array.isArray(expectedFormat) && Array.isArray(object)) {\n if (expectedFormat.length !== object.length) {\n return {\n isIdentic: false,\n error: `Array length mismatch at ${path}: expected ${expectedFormat.length} elements, got ${object.length}`,\n };\n }\n\n // Recursively check each element\n for (let i = 0; i < expectedFormat.length; i++) {\n const result = verifyIdenticObjectFormat(\n object[i],\n expectedFormat[i],\n `${path}[${i}]`\n );\n if (!result.isIdentic) {\n return result;\n }\n }\n\n return {\n isIdentic: true,\n };\n }\n\n // Handle objects (excluding null and arrays)\n if (\n typeof expectedFormat === 'object' &&\n typeof object === 'object' &&\n expectedFormat !== null &&\n object !== null\n ) {\n const expectedKeys = Object.keys(expectedFormat);\n const objectKeys = Object.keys(object);\n\n // Check if number of keys match\n if (expectedKeys.length !== objectKeys.length) {\n return {\n isIdentic: false,\n error: `Object keys count mismatch at ${path}: expected ${expectedKeys.length} keys, got ${objectKeys.length}`,\n };\n }\n\n // Check if each expected key is present in the object\n for (const key of expectedKeys) {\n if (!objectKeys.includes(key)) {\n return {\n isIdentic: false,\n error: `Missing key at ${path}: expected key \"${key}\" not found`,\n };\n }\n }\n\n // Check if there are any unexpected keys in the object\n for (const key of objectKeys) {\n if (!expectedKeys.includes(key)) {\n return {\n isIdentic: false,\n error: `Unexpected key at ${path}: key \"${key}\" was found but not expected`,\n };\n }\n }\n\n // Recursively check each property\n for (const key of expectedKeys) {\n const result = verifyIdenticObjectFormat(\n (object as Record<string, RecursiveType>)[key],\n (expectedFormat as Record<string, RecursiveType>)[key],\n `${path}.${key}`\n );\n if (!result.isIdentic) {\n return result;\n }\n }\n\n return {\n isIdentic: true,\n };\n }\n\n // For primitive types (string, number, boolean), just verify they're the same type\n // We don't check the actual values as per requirements\n return {\n isIdentic: true,\n };\n};\n"],"mappings":";;;;;;;;;;;;;AAsBA,MAAa,6BACX,QACA,gBACA,OAAe,WACqB;CAEpC,IAAI,mBAAmB,QAAQ,mBAAmB,QAAW;EAC3D,IAAI,mBAAmB,QACrB,OAAO;GACL,WAAW;GACX,OAAO,oBAAoB,KAAK,aAAa,mBAAmB,OAAO,SAAS,YAAY,QAAQ,WAAW,OAAO,SAAS,OAAO;EACxI;EAEF,OAAO,EACL,WAAW,KACb;CACF;CAIA,KACG,WAAW,QAAQ,WAAW,WAC/B,OAAO,mBAAmB,YAC1B,CAAC,MAAM,QAAQ,cAAc,GAE7B,OAAO,EAAE,WAAW,KAAK;CAI3B,MAAM,eAAe,MAAM,QAAQ,cAAc,IAC7C,UACA,OAAO;CACX,MAAM,aAAa,MAAM,QAAQ,MAAM,IAAI,UAAU,OAAO;CAG5D,IAAI,iBAAiB,YACnB,OAAO;EACL,WAAW;EACX,OAAO,oBAAoB,KAAK,aAAa,aAAa,QAAQ;CACpE;CAIF,IAAI,MAAM,QAAQ,cAAc,KAAK,MAAM,QAAQ,MAAM,GAAG;EAC1D,IAAI,eAAe,WAAW,OAAO,QACnC,OAAO;GACL,WAAW;GACX,OAAO,4BAA4B,KAAK,aAAa,eAAe,OAAO,iBAAiB,OAAO;EACrG;EAIF,KAAK,IAAI,IAAI,GAAG,IAAI,eAAe,QAAQ,KAAK;GAC9C,MAAM,SAAS,0BACb,OAAO,IACP,eAAe,IACf,GAAG,KAAK,GAAG,EAAE,EACf;GACA,IAAI,CAAC,OAAO,WACV,OAAO;EAEX;EAEA,OAAO,EACL,WAAW,KACb;CACF;CAGA,IACE,OAAO,mBAAmB,YAC1B,OAAO,WAAW,YAClB,mBAAmB,QACnB,WAAW,MACX;EACA,MAAM,eAAe,OAAO,KAAK,cAAc;EAC/C,MAAM,aAAa,OAAO,KAAK,MAAM;EAGrC,IAAI,aAAa,WAAW,WAAW,QACrC,OAAO;GACL,WAAW;GACX,OAAO,iCAAiC,KAAK,aAAa,aAAa,OAAO,aAAa,WAAW;EACxG;EAIF,KAAK,MAAM,OAAO,cAChB,IAAI,CAAC,WAAW,SAAS,GAAG,GAC1B,OAAO;GACL,WAAW;GACX,OAAO,kBAAkB,KAAK,kBAAkB,IAAI;EACtD;EAKJ,KAAK,MAAM,OAAO,YAChB,IAAI,CAAC,aAAa,SAAS,GAAG,GAC5B,OAAO;GACL,WAAW;GACX,OAAO,qBAAqB,KAAK,SAAS,IAAI;EAChD;EAKJ,KAAK,MAAM,OAAO,cAAc;GAC9B,MAAM,SAAS,0BACZ,OAAyC,MACzC,eAAiD,MAClD,GAAG,KAAK,GAAG,KACb;GACA,IAAI,CAAC,OAAO,WACV,OAAO;EAEX;EAEA,OAAO,EACL,WAAW,KACb;CACF;CAIA,OAAO,EACL,WAAW,KACb;AACF"}