diff --git a/manifest.json b/manifest.json index c428a05..3af19ff 100644 --- a/manifest.json +++ b/manifest.json @@ -22,6 +22,7 @@ "src/modules/vg-observe/module.js", "src/background/db/db-constants.js", "src/background/db/db-core.js", + "src/core/evidence-export-json.js", "src/background/gvl/gvl-vendor-normalizer.js", "src/background/gvl/gvl-vendor-relationship-normalizer.js", "src/background/gvl/gvl-catalog-normalizer.js", diff --git a/src/background.js b/src/background.js index b30b01c..cdb2b8e 100644 --- a/src/background.js +++ b/src/background.js @@ -37,6 +37,10 @@ async function handleVendorGetMessage(message, sender) { return handleFetchOfficialGvlMessage(); } + if (message.type === "export_evidence_json") { + return handleExportEvidenceJsonMessage(); + } + if (message.type === "start_evidence_maintenance_session") { return startEvidenceMaintenanceSession(message?.payload?.source); } @@ -169,6 +173,13 @@ async function handleGetEvidenceRetentionStatusMessage() { }; } +async function handleExportEvidenceJsonMessage() { + return { + success: true, + export: await exportVendorGetEvidenceJson() + }; +} + async function handleGetLatestGvlUpdateStatusMessage() { const db = await openVendorGetDb(); const latestSnapshot = await getLatestGvlSnapshotByVendorListVersion(db); diff --git a/src/core/evidence-export-json.js b/src/core/evidence-export-json.js new file mode 100644 index 0000000..98841d8 --- /dev/null +++ b/src/core/evidence-export-json.js @@ -0,0 +1,80 @@ +"use strict"; + +async function exportVendorGetEvidenceJson() { + const db = await openVendorGetDb(); + const storeNames = [...VENDORGET_EVIDENCE_STORE_NAMES]; + const stores = await exportVendorGetEvidenceStores(db, storeNames); + const summary = buildVendorGetEvidenceExportSummary(stores); + + return { + metadata: { + exportVersion: 1, + exportedAt: new Date().toISOString(), + project: "VG-Environment", + extension: "VendorGet", + dbName: db.name, + dbVersion: db.version, + stores: storeNames, + summary + }, + stores + }; +} + +function buildVendorGetEvidenceExportSummary(stores) { + const storeRecordCounts = {}; + let totalRecordCount = 0; + + for (const [storeName, storeExport] of Object.entries(stores)) { + const recordCount = storeExport.recordCount; + + storeRecordCounts[storeName] = recordCount; + totalRecordCount += recordCount; + } + + return { + totalRecordCount, + storeRecordCounts + }; +} + +function exportVendorGetEvidenceStores(db, storeNames) { + return new Promise((resolve, reject) => { + const stores = {}; + const tx = db.transaction(storeNames, "readonly"); + + tx.onerror = () => reject(tx.error); + tx.onabort = () => reject(tx.error); + tx.oncomplete = () => resolve(stores); + + for (const storeName of storeNames) { + const objectStore = tx.objectStore(storeName); + const storeExport = { + keyPath: objectStore.keyPath, + autoIncrement: objectStore.autoIncrement, + recordCount: 0, + records: [] + }; + + stores[storeName] = storeExport; + + const cursorRequest = objectStore.openCursor(); + + cursorRequest.onerror = () => reject(cursorRequest.error); + cursorRequest.onsuccess = () => { + const cursor = cursorRequest.result; + + if (!cursor) { + return; + } + + storeExport.records.push({ + key: cursor.key, + value: cursor.value + }); + storeExport.recordCount += 1; + cursor.continue(); + }; + } + }); +} diff --git a/src/popup/popup.html b/src/popup/popup.html index 16db664..f4aa9d5 100644 --- a/src/popup/popup.html +++ b/src/popup/popup.html @@ -63,6 +63,10 @@ + +