| 25 | } |
| 26 | |
| 27 | function getNewSrc(node) { |
| 28 | const { src } = node.properties |
| 29 | if (!src.startsWith('/')) return |
| 30 | |
| 31 | try { |
| 32 | const filePath = src.slice(1) |
| 33 | const stats = fs.statSync(filePath) |
| 34 | // The size is not perfect but it's good enough. The size is |
| 35 | // very fast to pick up without needing to do a deep hashing of the |
| 36 | // image's content. It's perfectly possible that someone edits an |
| 37 | // image and it's size doesn't change. Although very unlikely. |
| 38 | // The slightest change to the image is more likely to either increase |
| 39 | // or decrease the image size by at least 1 byte. |
| 40 | // Also, because of this limitation, we're not confident to cache the |
| 41 | // image more than say 24h. But in the unlikely event that someone does |
| 42 | // edit an image and the size doesn't change, there's always the |
| 43 | // escape hatch that you can soft-purge all manual CDN surrogate keys. |
| 44 | if (!stats.size) return |
| 45 | const hash = `${stats.size}` |
| 46 | const split = src.split('/') |
| 47 | split.splice(2, 0, `cb-${hash}`) |
| 48 | return split.join('/') |
| 49 | } catch (err) { |
| 50 | console.warn( |
| 51 | `Failed to get a hash for ${src} ` + |
| 52 | '(This is mostly harmless and can happen with outdated translations).' |
| 53 | ) |
| 54 | } |
| 55 | } |