|
1 | | -import {relativePath, joinPath} from './path.js' |
| 1 | +import {relativePath, joinPath, dirname} from './path.js' |
2 | 2 | import {glob, removeFile} from './fs.js' |
3 | 3 | import {outputDebug, outputContent, outputToken} from '../../public/node/output.js' |
4 | 4 | import archiver from 'archiver' |
@@ -52,16 +52,41 @@ export async function zip(options: ZipOptions): Promise<void> { |
52 | 52 | }) |
53 | 53 | archive.pipe(output) |
54 | 54 |
|
| 55 | + // Find parent directories to add explicitly to the archive |
| 56 | + const directoriesToAdd = new Set<string>() |
55 | 57 | for (const filePath of pathsToZip) { |
56 | | - const fileRelativePath = relativePath(inputDirectory, filePath) |
57 | | - archive.file(filePath, {name: fileRelativePath}) |
| 58 | + const relPath = relativePath(inputDirectory, filePath) |
| 59 | + collectParentDirectories(relPath, directoriesToAdd) |
| 60 | + } |
| 61 | + |
| 62 | + // Add directories, parents before children |
| 63 | + const sortedDirs = Array.from(directoriesToAdd).sort((left, right) => left.localeCompare(right)) |
| 64 | + for (const dir of sortedDirs) { |
| 65 | + const dirName = dir.endsWith('/') ? dir : `${dir}/` |
| 66 | + archive.append(Buffer.alloc(0), {name: dirName}) |
| 67 | + } |
| 68 | + |
| 69 | + // Add files |
| 70 | + for (const filePath of pathsToZip) { |
| 71 | + const rel = relativePath(inputDirectory, filePath) |
| 72 | + if (filePath && rel) archive.file(filePath, {name: rel}) |
58 | 73 | } |
59 | 74 |
|
60 | 75 | // eslint-disable-next-line @typescript-eslint/no-floating-promises |
61 | 76 | archive.finalize() |
62 | 77 | }) |
63 | 78 | } |
64 | 79 |
|
| 80 | +function collectParentDirectories(fileRelativePath: string, accumulator: Set<string>): void { |
| 81 | + let currentDir = dirname(fileRelativePath) |
| 82 | + while (currentDir && currentDir !== '.' && currentDir !== '/') { |
| 83 | + accumulator.add(currentDir) |
| 84 | + const parent = dirname(currentDir) |
| 85 | + if (parent === currentDir) break |
| 86 | + currentDir = parent |
| 87 | + } |
| 88 | +} |
| 89 | + |
65 | 90 | export interface BrotliOptions { |
66 | 91 | /** |
67 | 92 | * The directory to compress. |
@@ -133,7 +158,7 @@ export async function brotliCompress(options: BrotliOptions): Promise<void> { |
133 | 158 | // eslint-disable-next-line @typescript-eslint/no-floating-promises |
134 | 159 | archive.finalize() |
135 | 160 | }) |
136 | | - .catch((error) => reject(error)) |
| 161 | + .catch((error) => reject(error instanceof Error ? error : new Error(String(error)))) |
137 | 162 | }) |
138 | 163 |
|
139 | 164 | const tarContent = readFileSync(tempTarPath) |
|
0 commit comments