1 | import path from 'node:path';
|
2 | import {constants as BufferConstants} from 'node:buffer';
|
3 | import Vinyl from 'vinyl';
|
4 | import Yazl from 'yazl';
|
5 | import {getStreamAsBuffer, MaxBufferError} from 'get-stream';
|
6 | import {gulpPlugin} from 'gulp-plugin-extras';
|
7 |
|
8 | export default function gulpZip(filename, options) {
|
9 | if (!filename) {
|
10 | throw new Error('gulp-zip: `filename` required');
|
11 | }
|
12 |
|
13 | options = {
|
14 | compress: true,
|
15 | buffer: true,
|
16 | ...options,
|
17 | };
|
18 |
|
19 | let firstFile;
|
20 | const zip = new Yazl.ZipFile();
|
21 |
|
22 | return gulpPlugin('gulp-zip', async file => {
|
23 | firstFile ??= file;
|
24 |
|
25 |
|
26 | const pathname = file.relative.replaceAll('\\', '/');
|
27 |
|
28 | if (!pathname) {
|
29 | return;
|
30 | }
|
31 |
|
32 | if (file.isDirectory()) {
|
33 | zip.addEmptyDirectory(pathname, {
|
34 | mtime: options.modifiedTime || file.stat.mtime || new Date(),
|
35 |
|
36 |
|
37 |
|
38 |
|
39 | });
|
40 | } else {
|
41 | const stat = {
|
42 | compress: options.compress,
|
43 | mtime: options.modifiedTime || (file.stat ? file.stat.mtime : new Date()),
|
44 | mode: file.stat ? file.stat.mode : null,
|
45 | };
|
46 |
|
47 | if (file.isStream()) {
|
48 | zip.addReadStream(file.contents, pathname, stat);
|
49 | }
|
50 |
|
51 | if (file.isBuffer()) {
|
52 | zip.addBuffer(file.contents, pathname, stat);
|
53 | }
|
54 | }
|
55 | }, {
|
56 | supportsAnyType: true,
|
57 | async * onFinish() {
|
58 | zip.end();
|
59 |
|
60 | if (!firstFile) {
|
61 | return;
|
62 | }
|
63 |
|
64 | let data;
|
65 | if (options.buffer) {
|
66 | try {
|
67 | data = await getStreamAsBuffer(zip.outputStream, {maxBuffer: BufferConstants.MAX_LENGTH});
|
68 | } catch (error) {
|
69 | const error_ = error instanceof MaxBufferError ? new Error('The output ZIP file is too big to store in a buffer (larger than Buffer MAX_LENGTH). To output a stream instead, set the gulp-zip buffer option to `false`.') : error;
|
70 | throw error_;
|
71 | }
|
72 | } else {
|
73 | data = zip.outputStream;
|
74 | }
|
75 |
|
76 | yield new Vinyl({
|
77 | cwd: firstFile.cwd,
|
78 | base: firstFile.base,
|
79 | path: path.join(firstFile.base, filename),
|
80 | contents: data,
|
81 | });
|
82 | },
|
83 | });
|
84 | }
|