UNPKG

@lark-project/cli

Version:

飞书项目插件开发工具

116 lines (115 loc) 4.51 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.printCompareResult = exports.runCompare = exports.comparePointInfoMaps = void 0; const snapshot_1 = require("./snapshot"); const logger_1 = require("../logger"); /** * Compare two point_info_map objects (both in backend format). * Operates at the point key level, then recursively diffs field values. */ function comparePointInfoMaps(snapshot, remote) { const snapshotKeys = new Set(Object.keys(snapshot)); const remoteKeys = new Set(Object.keys(remote)); const matched = []; const missingInRemote = []; const extraInRemote = []; const diffs = []; for (const key of snapshotKeys) { if (!remoteKeys.has(key)) { missingInRemote.push(key); } else { const pointDiffs = diffObject(snapshot[key], remote[key], key); if (pointDiffs.length === 0) { matched.push(key); } else { diffs.push(...pointDiffs); } } } for (const key of remoteKeys) { if (!snapshotKeys.has(key)) { extraInRemote.push(key); } } return { matched, missingInRemote, extraInRemote, diffs }; } exports.comparePointInfoMaps = comparePointInfoMaps; function diffObject(a, b, prefix) { if (a === b) return []; if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) { return [{ key: prefix.split('.')[0], field: prefix, snapshotValue: a, remoteValue: b }]; } if (Array.isArray(a) && Array.isArray(b)) { const aStr = JSON.stringify(sortDeep(a)); const bStr = JSON.stringify(sortDeep(b)); if (aStr !== bStr) { return [{ key: prefix.split('.')[0], field: prefix, snapshotValue: a, remoteValue: b }]; } return []; } const result = []; const allKeys = new Set([...Object.keys(a), ...Object.keys(b)]); for (const k of allKeys) { result.push(...diffObject(a[k], b[k], `${prefix}.${k}`)); } return result; } function sortDeep(val) { if (Array.isArray(val)) return [...val].sort().map(sortDeep); if (val && typeof val === 'object') { return Object.fromEntries(Object.entries(val).sort().map(([k, v]) => [k, sortDeep(v)])); } return val; } function runCompare(caseId, remotePointInfoMap) { const snapshot = (0, snapshot_1.loadSnapshot)(caseId); if (!snapshot) { logger_1.logger.error(`No snapshot found for case ${caseId}. Run update --save-snapshot --case-id ${caseId} first.`); process.exit(1); } const { matched, missingInRemote, extraInRemote, diffs } = comparePointInfoMaps(snapshot, remotePointInfoMap); const status = missingInRemote.length === 0 && diffs.length === 0 ? 'pass' : matched.length > 0 && diffs.length < matched.length ? 'partial' : 'fail'; const result = { caseId, status, matched, missingInRemote, extraInRemote, diffs, snapshotPath: (0, snapshot_1.getSnapshotPath)(caseId), evaluatedAt: new Date().toISOString(), }; (0, snapshot_1.saveResult)(caseId, result); (0, snapshot_1.updateSummary)(caseId, result); return result; } exports.runCompare = runCompare; function printCompareResult(result) { const statusEmoji = result.status === 'pass' ? '✅' : result.status === 'partial' ? '⚠️' : '❌'; logger_1.logger.info(`\n${statusEmoji} Compare result for [${result.caseId}]: ${result.status.toUpperCase()}`); logger_1.logger.info(` Matched keys: ${result.matched.length}`); if (result.missingInRemote.length > 0) { logger_1.logger.error(` Missing in remote: ${result.missingInRemote.join(', ')}`); } if (result.extraInRemote.length > 0) { logger_1.logger.info(` Extra in remote: ${result.extraInRemote.join(', ')}`); } if (result.diffs.length > 0) { logger_1.logger.error(` Field diffs (${result.diffs.length}):`); for (const d of result.diffs) { logger_1.logger.error(` ${d.field}`); logger_1.logger.error(` snapshot: ${JSON.stringify(d.snapshotValue)}`); logger_1.logger.error(` remote: ${JSON.stringify(d.remoteValue)}`); } } logger_1.logger.info(` Results saved to .point-eval/results/${result.caseId}.json`); } exports.printCompareResult = printCompareResult;