( targetPath: string, data: string | Uint8Array, )
| 173 | * Writes to a temp file in the same directory, then renames. |
| 174 | */ |
| 175 | export async function atomicWriteToZipCache( |
| 176 | targetPath: string, |
| 177 | data: string | Uint8Array, |
| 178 | ): Promise<void> { |
| 179 | const dir = dirname(targetPath) |
| 180 | await getFsImplementation().mkdir(dir) |
| 181 | |
| 182 | const tmpName = `.${basename(targetPath)}.tmp.${randomBytes(4).toString('hex')}` |
| 183 | const tmpPath = join(dir, tmpName) |
| 184 | |
| 185 | try { |
| 186 | if (typeof data === 'string') { |
| 187 | await writeFile(tmpPath, data, { encoding: 'utf-8' }) |
| 188 | } else { |
| 189 | await writeFile(tmpPath, data) |
| 190 | } |
| 191 | await rename(tmpPath, targetPath) |
| 192 | } catch (error) { |
| 193 | // Clean up tmp file on failure |
| 194 | try { |
| 195 | await rm(tmpPath, { force: true }) |
| 196 | } catch { |
| 197 | // ignore cleanup errors |
| 198 | } |
| 199 | throw error |
| 200 | } |
| 201 | } |
| 202 | |
| 203 | // fflate's ZippableFile tuple form: [data, opts]. Using the tuple lets us |
| 204 | // store {os, attrs} so parseZipModes can recover exec bits on extraction. |
no test coverage detected