* Load the install counts cache from disk. * Returns null if the file doesn't exist, is invalid, or is stale (>24h old).
()
| 60 | * Returns null if the file doesn't exist, is invalid, or is stale (>24h old). |
| 61 | */ |
| 62 | async function loadInstallCountsCache(): Promise<InstallCountsCache | null> { |
| 63 | const cachePath = getInstallCountsCachePath() |
| 64 | |
| 65 | try { |
| 66 | const content = await readFile(cachePath, { encoding: 'utf-8' }) |
| 67 | const parsed = jsonParse(content) as unknown |
| 68 | |
| 69 | // Validate basic structure |
| 70 | if ( |
| 71 | typeof parsed !== 'object' || |
| 72 | parsed === null || |
| 73 | !('version' in parsed) || |
| 74 | !('fetchedAt' in parsed) || |
| 75 | !('counts' in parsed) |
| 76 | ) { |
| 77 | logForDebugging('Install counts cache has invalid structure') |
| 78 | return null |
| 79 | } |
| 80 | |
| 81 | const cache = parsed as { |
| 82 | version: unknown |
| 83 | fetchedAt: unknown |
| 84 | counts: unknown |
| 85 | } |
| 86 | |
| 87 | // Validate version |
| 88 | if (cache.version !== INSTALL_COUNTS_CACHE_VERSION) { |
| 89 | logForDebugging( |
| 90 | `Install counts cache version mismatch (got ${cache.version}, expected ${INSTALL_COUNTS_CACHE_VERSION})`, |
| 91 | ) |
| 92 | return null |
| 93 | } |
| 94 | |
| 95 | // Validate fetchedAt and counts |
| 96 | if (typeof cache.fetchedAt !== 'string' || !Array.isArray(cache.counts)) { |
| 97 | logForDebugging('Install counts cache has invalid structure') |
| 98 | return null |
| 99 | } |
| 100 | |
| 101 | // Validate fetchedAt is a valid date |
| 102 | const fetchedAt = new Date(cache.fetchedAt).getTime() |
| 103 | if (Number.isNaN(fetchedAt)) { |
| 104 | logForDebugging('Install counts cache has invalid fetchedAt timestamp') |
| 105 | return null |
| 106 | } |
| 107 | |
| 108 | // Validate count entries have required fields |
| 109 | const validCounts = cache.counts.every( |
| 110 | (entry): entry is { plugin: string; unique_installs: number } => |
| 111 | typeof entry === 'object' && |
| 112 | entry !== null && |
| 113 | typeof entry.plugin === 'string' && |
| 114 | typeof entry.unique_installs === 'number', |
| 115 | ) |
| 116 | if (!validCounts) { |
| 117 | logForDebugging('Install counts cache has malformed entries') |
| 118 | return null |
| 119 | } |
no test coverage detected