@helloao/cli 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/actions.d.ts +57 -0
- package/actions.js +262 -0
- package/cli.d.ts +2 -0
- package/cli.js +139 -0
- package/db.d.ts +110 -0
- package/db.js +754 -0
- package/downloads.d.ts +2 -0
- package/downloads.js +12 -0
- package/files.d.ts +56 -0
- package/files.js +232 -0
- package/index.d.ts +8 -0
- package/index.js +38 -0
- package/migrations/20240420231455_initial/migration.sql +66 -0
- package/migrations/20240623183848_add_book_order/migration.sql +26 -0
- package/migrations/20240629194121_add_chapter_links/migration.sql +45 -0
- package/migrations/20240629194513_add_chapter_content/migration.sql +30 -0
- package/migrations/20240705221833_remove_unused_columns/migration.sql +27 -0
- package/migrations/20240711173108_add_chapter_audio/migration.sql +13 -0
- package/migrations/20240724212651_add_hashing/migration.sql +25 -0
- package/node_modules/@zip.js/zip.js/LICENSE +28 -0
- package/node_modules/@zip.js/zip.js/README.md +173 -0
- package/node_modules/@zip.js/zip.js/deno.json +8 -0
- package/node_modules/@zip.js/zip.js/dist/README.md +28 -0
- package/node_modules/@zip.js/zip.js/dist/z-worker-fflate.js +1 -0
- package/node_modules/@zip.js/zip.js/dist/z-worker-pako.js +1 -0
- package/node_modules/@zip.js/zip.js/dist/z-worker.js +1 -0
- package/node_modules/@zip.js/zip.js/dist/zip-fs-full.js +11935 -0
- package/node_modules/@zip.js/zip.js/dist/zip-fs-full.min.js +1 -0
- package/node_modules/@zip.js/zip.js/dist/zip-fs.js +6079 -0
- package/node_modules/@zip.js/zip.js/dist/zip-fs.min.js +1 -0
- package/node_modules/@zip.js/zip.js/dist/zip-full.js +9463 -0
- package/node_modules/@zip.js/zip.js/dist/zip-full.min.js +1 -0
- package/node_modules/@zip.js/zip.js/dist/zip-no-worker-deflate.min.js +1 -0
- package/node_modules/@zip.js/zip.js/dist/zip-no-worker-inflate.min.js +1 -0
- package/node_modules/@zip.js/zip.js/dist/zip-no-worker.min.js +1 -0
- package/node_modules/@zip.js/zip.js/dist/zip.js +5240 -0
- package/node_modules/@zip.js/zip.js/dist/zip.min.js +1 -0
- package/node_modules/@zip.js/zip.js/index-fflate.js +82 -0
- package/node_modules/@zip.js/zip.js/index.cjs +11927 -0
- package/node_modules/@zip.js/zip.js/index.d.ts +2048 -0
- package/node_modules/@zip.js/zip.js/index.js +87 -0
- package/node_modules/@zip.js/zip.js/index.min.js +1 -0
- package/node_modules/@zip.js/zip.js/lib/core/codec-pool.js +127 -0
- package/node_modules/@zip.js/zip.js/lib/core/codec-worker.js +348 -0
- package/node_modules/@zip.js/zip.js/lib/core/configuration.js +127 -0
- package/node_modules/@zip.js/zip.js/lib/core/constants.js +114 -0
- package/node_modules/@zip.js/zip.js/lib/core/io.js +749 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/aes-crypto-stream.js +326 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/codec-stream.js +154 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/codecs/crc32.js +63 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/codecs/deflate.js +2063 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/codecs/inflate.js +2167 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/codecs/sjcl.js +827 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/common-crypto.js +55 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/crc32-stream.js +56 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/stream-adapter.js +55 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/zip-crypto-stream.js +162 -0
- package/node_modules/@zip.js/zip.js/lib/core/streams/zip-entry-stream.js +165 -0
- package/node_modules/@zip.js/zip.js/lib/core/util/cp437-decode.js +48 -0
- package/node_modules/@zip.js/zip.js/lib/core/util/decode-text.js +43 -0
- package/node_modules/@zip.js/zip.js/lib/core/util/default-mime-type.js +38 -0
- package/node_modules/@zip.js/zip.js/lib/core/util/encode-text.js +48 -0
- package/node_modules/@zip.js/zip.js/lib/core/util/mime-type.js +1639 -0
- package/node_modules/@zip.js/zip.js/lib/core/util/stream-codec-shim.js +91 -0
- package/node_modules/@zip.js/zip.js/lib/core/z-worker-core.js +176 -0
- package/node_modules/@zip.js/zip.js/lib/core/zip-entry.js +86 -0
- package/node_modules/@zip.js/zip.js/lib/core/zip-fs-core.js +865 -0
- package/node_modules/@zip.js/zip.js/lib/core/zip-reader.js +757 -0
- package/node_modules/@zip.js/zip.js/lib/core/zip-writer.js +1186 -0
- package/node_modules/@zip.js/zip.js/lib/z-worker-bootstrap-fflate.js +40 -0
- package/node_modules/@zip.js/zip.js/lib/z-worker-bootstrap-pako.js +39 -0
- package/node_modules/@zip.js/zip.js/lib/z-worker-fflate.js +40 -0
- package/node_modules/@zip.js/zip.js/lib/z-worker-inline-template.js +42 -0
- package/node_modules/@zip.js/zip.js/lib/z-worker-inline.js +1 -0
- package/node_modules/@zip.js/zip.js/lib/z-worker.js +38 -0
- package/node_modules/@zip.js/zip.js/lib/zip-data-uri.js +53 -0
- package/node_modules/@zip.js/zip.js/lib/zip-fflate-shim.js +37 -0
- package/node_modules/@zip.js/zip.js/lib/zip-fs.js +53 -0
- package/node_modules/@zip.js/zip.js/lib/zip-full-fflate.js +53 -0
- package/node_modules/@zip.js/zip.js/lib/zip-full.js +54 -0
- package/node_modules/@zip.js/zip.js/lib/zip-no-worker-deflate.js +42 -0
- package/node_modules/@zip.js/zip.js/lib/zip-no-worker-fflate-deflate.js +42 -0
- package/node_modules/@zip.js/zip.js/lib/zip-no-worker-fflate-inflate.js +42 -0
- package/node_modules/@zip.js/zip.js/lib/zip-no-worker-fflate.js +43 -0
- package/node_modules/@zip.js/zip.js/lib/zip-no-worker-inflate.js +42 -0
- package/node_modules/@zip.js/zip.js/lib/zip-no-worker.js +44 -0
- package/node_modules/@zip.js/zip.js/lib/zip.js +52 -0
- package/node_modules/@zip.js/zip.js/package.json +86 -0
- package/package.json +43 -0
- package/prisma-gen/default.d.ts +1 -0
- package/prisma-gen/default.js +1 -0
- package/prisma-gen/edge.d.ts +1 -0
- package/prisma-gen/edge.js +242 -0
- package/prisma-gen/index-browser.js +236 -0
- package/prisma-gen/index.d.ts +13248 -0
- package/prisma-gen/index.js +265 -0
- package/prisma-gen/runtime/edge-esm.js +28 -0
- package/prisma-gen/runtime/edge.js +28 -0
- package/prisma-gen/runtime/index-browser.d.ts +365 -0
- package/prisma-gen/runtime/index-browser.js +13 -0
- package/prisma-gen/runtime/library.d.ts +3168 -0
- package/prisma-gen/runtime/library.js +140 -0
- package/prisma-gen/runtime/wasm.js +29 -0
- package/prisma-gen/wasm.d.ts +1 -0
- package/prisma-gen/wasm.js +236 -0
- package/s3.d.ts +14 -0
- package/s3.js +76 -0
- package/schema.prisma +154 -0
- package/uploads.d.ts +54 -0
- package/uploads.js +141 -0
|
@@ -0,0 +1,1186 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2022 Gildas Lormeau. All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
1. Redistributions of source code must retain the above copyright notice,
|
|
8
|
+
this list of conditions and the following disclaimer.
|
|
9
|
+
|
|
10
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
11
|
+
notice, this list of conditions and the following disclaimer in
|
|
12
|
+
the documentation and/or other materials provided with the distribution.
|
|
13
|
+
|
|
14
|
+
3. The names of the authors may not be used to endorse or promote products
|
|
15
|
+
derived from this software without specific prior written permission.
|
|
16
|
+
|
|
17
|
+
THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
|
18
|
+
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
|
20
|
+
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
21
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
22
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
|
23
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
24
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
25
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
26
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/* global BigInt, TransformStream, Response */
|
|
30
|
+
// deno-lint-ignore-file no-this-alias
|
|
31
|
+
|
|
32
|
+
import {
|
|
33
|
+
MAX_32_BITS,
|
|
34
|
+
MAX_16_BITS,
|
|
35
|
+
COMPRESSION_METHOD_DEFLATE,
|
|
36
|
+
COMPRESSION_METHOD_STORE,
|
|
37
|
+
COMPRESSION_METHOD_AES,
|
|
38
|
+
SPLIT_ZIP_FILE_SIGNATURE,
|
|
39
|
+
LOCAL_FILE_HEADER_SIGNATURE,
|
|
40
|
+
DATA_DESCRIPTOR_RECORD_SIGNATURE,
|
|
41
|
+
CENTRAL_FILE_HEADER_SIGNATURE,
|
|
42
|
+
END_OF_CENTRAL_DIR_SIGNATURE,
|
|
43
|
+
ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE,
|
|
44
|
+
ZIP64_END_OF_CENTRAL_DIR_SIGNATURE,
|
|
45
|
+
EXTRAFIELD_TYPE_AES,
|
|
46
|
+
EXTRAFIELD_TYPE_ZIP64,
|
|
47
|
+
EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP,
|
|
48
|
+
EXTRAFIELD_TYPE_NTFS,
|
|
49
|
+
EXTRAFIELD_TYPE_NTFS_TAG1,
|
|
50
|
+
EXTRAFIELD_TYPE_USDZ,
|
|
51
|
+
END_OF_CENTRAL_DIR_LENGTH,
|
|
52
|
+
ZIP64_END_OF_CENTRAL_DIR_LENGTH,
|
|
53
|
+
ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH,
|
|
54
|
+
ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH,
|
|
55
|
+
BITFLAG_ENCRYPTED,
|
|
56
|
+
BITFLAG_DATA_DESCRIPTOR,
|
|
57
|
+
BITFLAG_LANG_ENCODING_FLAG,
|
|
58
|
+
FILE_ATTR_MSDOS_DIR_MASK,
|
|
59
|
+
VERSION_DEFLATE,
|
|
60
|
+
VERSION_ZIP64,
|
|
61
|
+
VERSION_AES,
|
|
62
|
+
DIRECTORY_SIGNATURE,
|
|
63
|
+
MIN_DATE,
|
|
64
|
+
MAX_DATE,
|
|
65
|
+
UNDEFINED_VALUE
|
|
66
|
+
} from "./constants.js";
|
|
67
|
+
import {
|
|
68
|
+
getConfiguration,
|
|
69
|
+
getChunkSize
|
|
70
|
+
} from "./configuration.js";
|
|
71
|
+
import {
|
|
72
|
+
CODEC_DEFLATE,
|
|
73
|
+
runWorker
|
|
74
|
+
} from "./codec-pool.js";
|
|
75
|
+
import {
|
|
76
|
+
initStream,
|
|
77
|
+
initReader,
|
|
78
|
+
initWriter
|
|
79
|
+
} from "./io.js";
|
|
80
|
+
import { encodeText } from "./util/encode-text.js";
|
|
81
|
+
import {
|
|
82
|
+
PROPERTY_NAME_LAST_MODIFICATION_DATE,
|
|
83
|
+
PROPERTY_NAME_LAST_ACCESS_DATE,
|
|
84
|
+
PROPERTY_NAME_CREATION_DATE,
|
|
85
|
+
PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTE,
|
|
86
|
+
PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTE,
|
|
87
|
+
PROPERTY_NAME_MS_DOS_COMPATIBLE,
|
|
88
|
+
PROPERTY_NAME_ZIP64,
|
|
89
|
+
Entry
|
|
90
|
+
} from "./zip-entry.js";
|
|
91
|
+
|
|
92
|
+
const ERR_DUPLICATED_NAME = "File already exists";
|
|
93
|
+
const ERR_INVALID_COMMENT = "Zip file comment exceeds 64KB";
|
|
94
|
+
const ERR_INVALID_ENTRY_COMMENT = "File entry comment exceeds 64KB";
|
|
95
|
+
const ERR_INVALID_ENTRY_NAME = "File entry name exceeds 64KB";
|
|
96
|
+
const ERR_INVALID_VERSION = "Version exceeds 65535";
|
|
97
|
+
const ERR_INVALID_ENCRYPTION_STRENGTH = "The strength must equal 1, 2, or 3";
|
|
98
|
+
const ERR_INVALID_EXTRAFIELD_TYPE = "Extra field type exceeds 65535";
|
|
99
|
+
const ERR_INVALID_EXTRAFIELD_DATA = "Extra field data exceeds 64KB";
|
|
100
|
+
const ERR_UNSUPPORTED_FORMAT = "Zip64 is not supported (make sure 'keepOrder' is set to 'true')";
|
|
101
|
+
|
|
102
|
+
const EXTRAFIELD_DATA_AES = new Uint8Array([0x07, 0x00, 0x02, 0x00, 0x41, 0x45, 0x03, 0x00, 0x00]);
|
|
103
|
+
|
|
104
|
+
let workers = 0;
|
|
105
|
+
const pendingEntries = [];
|
|
106
|
+
|
|
107
|
+
class ZipWriter {
|
|
108
|
+
|
|
109
|
+
constructor(writer, options = {}) {
|
|
110
|
+
writer = initWriter(writer);
|
|
111
|
+
const addSplitZipSignature =
|
|
112
|
+
writer.availableSize !== UNDEFINED_VALUE && writer.availableSize > 0 && writer.availableSize !== Infinity &&
|
|
113
|
+
writer.maxSize !== UNDEFINED_VALUE && writer.maxSize > 0 && writer.maxSize !== Infinity;
|
|
114
|
+
Object.assign(this, {
|
|
115
|
+
writer,
|
|
116
|
+
addSplitZipSignature,
|
|
117
|
+
options,
|
|
118
|
+
config: getConfiguration(),
|
|
119
|
+
files: new Map(),
|
|
120
|
+
filenames: new Set(),
|
|
121
|
+
offset: writer.writable.size,
|
|
122
|
+
pendingEntriesSize: 0,
|
|
123
|
+
pendingAddFileCalls: new Set(),
|
|
124
|
+
bufferedWrites: 0
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async add(name = "", reader, options = {}) {
|
|
129
|
+
const zipWriter = this;
|
|
130
|
+
const {
|
|
131
|
+
pendingAddFileCalls,
|
|
132
|
+
config
|
|
133
|
+
} = zipWriter;
|
|
134
|
+
if (workers < config.maxWorkers) {
|
|
135
|
+
workers++;
|
|
136
|
+
} else {
|
|
137
|
+
await new Promise(resolve => pendingEntries.push(resolve));
|
|
138
|
+
}
|
|
139
|
+
let promiseAddFile;
|
|
140
|
+
try {
|
|
141
|
+
name = name.trim();
|
|
142
|
+
if (zipWriter.filenames.has(name)) {
|
|
143
|
+
throw new Error(ERR_DUPLICATED_NAME);
|
|
144
|
+
}
|
|
145
|
+
zipWriter.filenames.add(name);
|
|
146
|
+
promiseAddFile = addFile(zipWriter, name, reader, options);
|
|
147
|
+
pendingAddFileCalls.add(promiseAddFile);
|
|
148
|
+
return await promiseAddFile;
|
|
149
|
+
} catch (error) {
|
|
150
|
+
zipWriter.filenames.delete(name);
|
|
151
|
+
throw error;
|
|
152
|
+
} finally {
|
|
153
|
+
pendingAddFileCalls.delete(promiseAddFile);
|
|
154
|
+
const pendingEntry = pendingEntries.shift();
|
|
155
|
+
if (pendingEntry) {
|
|
156
|
+
pendingEntry();
|
|
157
|
+
} else {
|
|
158
|
+
workers--;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async close(comment = new Uint8Array(), options = {}) {
|
|
164
|
+
const zipWriter = this;
|
|
165
|
+
const { pendingAddFileCalls, writer } = this;
|
|
166
|
+
const { writable } = writer;
|
|
167
|
+
while (pendingAddFileCalls.size) {
|
|
168
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
169
|
+
}
|
|
170
|
+
await closeFile(this, comment, options);
|
|
171
|
+
const preventClose = getOptionValue(zipWriter, options, "preventClose");
|
|
172
|
+
if (!preventClose) {
|
|
173
|
+
await writable.getWriter().close();
|
|
174
|
+
}
|
|
175
|
+
return writer.getData ? writer.getData() : writable;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
class ZipWriterStream {
|
|
180
|
+
|
|
181
|
+
constructor(options = {}) {
|
|
182
|
+
const { readable, writable } = new TransformStream();
|
|
183
|
+
this.readable = readable;
|
|
184
|
+
this.zipWriter = new ZipWriter(writable, options);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
transform(path) {
|
|
188
|
+
const { readable, writable } = new TransformStream({
|
|
189
|
+
flush: () => { this.zipWriter.close(); }
|
|
190
|
+
});
|
|
191
|
+
this.zipWriter.add(path, readable);
|
|
192
|
+
return { readable: this.readable, writable };
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
writable(path) {
|
|
196
|
+
const { readable, writable } = new TransformStream();
|
|
197
|
+
this.zipWriter.add(path, readable);
|
|
198
|
+
return writable;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
close(comment = undefined, options = {}) {
|
|
202
|
+
return this.zipWriter.close(comment, options);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export {
|
|
207
|
+
ZipWriter,
|
|
208
|
+
ZipWriterStream,
|
|
209
|
+
ERR_DUPLICATED_NAME,
|
|
210
|
+
ERR_INVALID_COMMENT,
|
|
211
|
+
ERR_INVALID_ENTRY_NAME,
|
|
212
|
+
ERR_INVALID_ENTRY_COMMENT,
|
|
213
|
+
ERR_INVALID_VERSION,
|
|
214
|
+
ERR_INVALID_EXTRAFIELD_TYPE,
|
|
215
|
+
ERR_INVALID_EXTRAFIELD_DATA,
|
|
216
|
+
ERR_INVALID_ENCRYPTION_STRENGTH,
|
|
217
|
+
ERR_UNSUPPORTED_FORMAT
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
async function addFile(zipWriter, name, reader, options) {
|
|
221
|
+
name = name.trim();
|
|
222
|
+
if (options.directory && (!name.endsWith(DIRECTORY_SIGNATURE))) {
|
|
223
|
+
name += DIRECTORY_SIGNATURE;
|
|
224
|
+
} else {
|
|
225
|
+
options.directory = name.endsWith(DIRECTORY_SIGNATURE);
|
|
226
|
+
}
|
|
227
|
+
const encode = getOptionValue(zipWriter, options, "encodeText", encodeText);
|
|
228
|
+
let rawFilename = encode(name);
|
|
229
|
+
if (rawFilename === UNDEFINED_VALUE) {
|
|
230
|
+
rawFilename = encodeText(name);
|
|
231
|
+
}
|
|
232
|
+
if (getLength(rawFilename) > MAX_16_BITS) {
|
|
233
|
+
throw new Error(ERR_INVALID_ENTRY_NAME);
|
|
234
|
+
}
|
|
235
|
+
const comment = options.comment || "";
|
|
236
|
+
let rawComment = encode(comment);
|
|
237
|
+
if (rawComment === UNDEFINED_VALUE) {
|
|
238
|
+
rawComment = encodeText(comment);
|
|
239
|
+
}
|
|
240
|
+
if (getLength(rawComment) > MAX_16_BITS) {
|
|
241
|
+
throw new Error(ERR_INVALID_ENTRY_COMMENT);
|
|
242
|
+
}
|
|
243
|
+
const version = getOptionValue(zipWriter, options, "version", VERSION_DEFLATE);
|
|
244
|
+
if (version > MAX_16_BITS) {
|
|
245
|
+
throw new Error(ERR_INVALID_VERSION);
|
|
246
|
+
}
|
|
247
|
+
const versionMadeBy = getOptionValue(zipWriter, options, "versionMadeBy", 20);
|
|
248
|
+
if (versionMadeBy > MAX_16_BITS) {
|
|
249
|
+
throw new Error(ERR_INVALID_VERSION);
|
|
250
|
+
}
|
|
251
|
+
const lastModDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_MODIFICATION_DATE, new Date());
|
|
252
|
+
const lastAccessDate = getOptionValue(zipWriter, options, PROPERTY_NAME_LAST_ACCESS_DATE);
|
|
253
|
+
const creationDate = getOptionValue(zipWriter, options, PROPERTY_NAME_CREATION_DATE);
|
|
254
|
+
const msDosCompatible = getOptionValue(zipWriter, options, PROPERTY_NAME_MS_DOS_COMPATIBLE, true);
|
|
255
|
+
const internalFileAttribute = getOptionValue(zipWriter, options, PROPERTY_NAME_INTERNAL_FILE_ATTRIBUTE, 0);
|
|
256
|
+
const externalFileAttribute = getOptionValue(zipWriter, options, PROPERTY_NAME_EXTERNAL_FILE_ATTRIBUTE, 0);
|
|
257
|
+
const password = getOptionValue(zipWriter, options, "password");
|
|
258
|
+
const rawPassword = getOptionValue(zipWriter, options, "rawPassword");
|
|
259
|
+
const encryptionStrength = getOptionValue(zipWriter, options, "encryptionStrength", 3);
|
|
260
|
+
const zipCrypto = getOptionValue(zipWriter, options, "zipCrypto");
|
|
261
|
+
const extendedTimestamp = getOptionValue(zipWriter, options, "extendedTimestamp", true);
|
|
262
|
+
const keepOrder = getOptionValue(zipWriter, options, "keepOrder", true);
|
|
263
|
+
const level = getOptionValue(zipWriter, options, "level");
|
|
264
|
+
const useWebWorkers = getOptionValue(zipWriter, options, "useWebWorkers");
|
|
265
|
+
const bufferedWrite = getOptionValue(zipWriter, options, "bufferedWrite");
|
|
266
|
+
const dataDescriptorSignature = getOptionValue(zipWriter, options, "dataDescriptorSignature", false);
|
|
267
|
+
const signal = getOptionValue(zipWriter, options, "signal");
|
|
268
|
+
const useCompressionStream = getOptionValue(zipWriter, options, "useCompressionStream");
|
|
269
|
+
let dataDescriptor = getOptionValue(zipWriter, options, "dataDescriptor", true);
|
|
270
|
+
let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
|
|
271
|
+
if (password !== UNDEFINED_VALUE && encryptionStrength !== UNDEFINED_VALUE && (encryptionStrength < 1 || encryptionStrength > 3)) {
|
|
272
|
+
throw new Error(ERR_INVALID_ENCRYPTION_STRENGTH);
|
|
273
|
+
}
|
|
274
|
+
let rawExtraField = new Uint8Array();
|
|
275
|
+
const { extraField } = options;
|
|
276
|
+
if (extraField) {
|
|
277
|
+
let extraFieldSize = 0;
|
|
278
|
+
let offset = 0;
|
|
279
|
+
extraField.forEach(data => extraFieldSize += 4 + getLength(data));
|
|
280
|
+
rawExtraField = new Uint8Array(extraFieldSize);
|
|
281
|
+
extraField.forEach((data, type) => {
|
|
282
|
+
if (type > MAX_16_BITS) {
|
|
283
|
+
throw new Error(ERR_INVALID_EXTRAFIELD_TYPE);
|
|
284
|
+
}
|
|
285
|
+
if (getLength(data) > MAX_16_BITS) {
|
|
286
|
+
throw new Error(ERR_INVALID_EXTRAFIELD_DATA);
|
|
287
|
+
}
|
|
288
|
+
arraySet(rawExtraField, new Uint16Array([type]), offset);
|
|
289
|
+
arraySet(rawExtraField, new Uint16Array([getLength(data)]), offset + 2);
|
|
290
|
+
arraySet(rawExtraField, data, offset + 4);
|
|
291
|
+
offset += 4 + getLength(data);
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
let maximumCompressedSize = 0;
|
|
295
|
+
let maximumEntrySize = 0;
|
|
296
|
+
let uncompressedSize = 0;
|
|
297
|
+
const zip64Enabled = zip64 === true;
|
|
298
|
+
if (reader) {
|
|
299
|
+
reader = initReader(reader);
|
|
300
|
+
await initStream(reader);
|
|
301
|
+
if (reader.size === UNDEFINED_VALUE) {
|
|
302
|
+
dataDescriptor = true;
|
|
303
|
+
if (zip64 || zip64 === UNDEFINED_VALUE) {
|
|
304
|
+
zip64 = true;
|
|
305
|
+
uncompressedSize = maximumCompressedSize = MAX_32_BITS + 1;
|
|
306
|
+
}
|
|
307
|
+
} else {
|
|
308
|
+
uncompressedSize = reader.size;
|
|
309
|
+
maximumCompressedSize = getMaximumCompressedSize(uncompressedSize);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
const { diskOffset, diskNumber, maxSize } = zipWriter.writer;
|
|
313
|
+
const zip64UncompressedSize = zip64Enabled || uncompressedSize > MAX_32_BITS;
|
|
314
|
+
const zip64CompressedSize = zip64Enabled || maximumCompressedSize > MAX_32_BITS;
|
|
315
|
+
const zip64Offset = zip64Enabled || zipWriter.offset + zipWriter.pendingEntriesSize - diskOffset > MAX_32_BITS;
|
|
316
|
+
const supportZip64SplitFile = getOptionValue(zipWriter, options, "supportZip64SplitFile", true);
|
|
317
|
+
const zip64DiskNumberStart = (supportZip64SplitFile && zip64Enabled) || diskNumber + Math.ceil(zipWriter.pendingEntriesSize / maxSize) > MAX_16_BITS;
|
|
318
|
+
if (zip64Offset || zip64UncompressedSize || zip64CompressedSize || zip64DiskNumberStart) {
|
|
319
|
+
if (zip64 === false || !keepOrder) {
|
|
320
|
+
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
321
|
+
} else {
|
|
322
|
+
zip64 = true;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
zip64 = zip64 || false;
|
|
326
|
+
options = Object.assign({}, options, {
|
|
327
|
+
rawFilename,
|
|
328
|
+
rawComment,
|
|
329
|
+
version,
|
|
330
|
+
versionMadeBy,
|
|
331
|
+
lastModDate,
|
|
332
|
+
lastAccessDate,
|
|
333
|
+
creationDate,
|
|
334
|
+
rawExtraField,
|
|
335
|
+
zip64,
|
|
336
|
+
zip64UncompressedSize,
|
|
337
|
+
zip64CompressedSize,
|
|
338
|
+
zip64Offset,
|
|
339
|
+
zip64DiskNumberStart,
|
|
340
|
+
password,
|
|
341
|
+
rawPassword,
|
|
342
|
+
level: !useCompressionStream && (zipWriter.config.CompressionStream === UNDEFINED_VALUE && zipWriter.config.CompressionStreamNative === UNDEFINED_VALUE) ? 0 : level,
|
|
343
|
+
useWebWorkers,
|
|
344
|
+
encryptionStrength,
|
|
345
|
+
extendedTimestamp,
|
|
346
|
+
zipCrypto,
|
|
347
|
+
bufferedWrite,
|
|
348
|
+
keepOrder,
|
|
349
|
+
dataDescriptor,
|
|
350
|
+
dataDescriptorSignature,
|
|
351
|
+
signal,
|
|
352
|
+
msDosCompatible,
|
|
353
|
+
internalFileAttribute,
|
|
354
|
+
externalFileAttribute,
|
|
355
|
+
useCompressionStream
|
|
356
|
+
});
|
|
357
|
+
const headerInfo = getHeaderInfo(options);
|
|
358
|
+
const dataDescriptorInfo = getDataDescriptorInfo(options);
|
|
359
|
+
const metadataSize = getLength(headerInfo.localHeaderArray, dataDescriptorInfo.dataDescriptorArray);
|
|
360
|
+
maximumEntrySize = metadataSize + maximumCompressedSize;
|
|
361
|
+
if (zipWriter.options.usdz) {
|
|
362
|
+
maximumEntrySize += maximumEntrySize + 64;
|
|
363
|
+
}
|
|
364
|
+
zipWriter.pendingEntriesSize += maximumEntrySize;
|
|
365
|
+
let fileEntry;
|
|
366
|
+
try {
|
|
367
|
+
fileEntry = await getFileEntry(zipWriter, name, reader, { headerInfo, dataDescriptorInfo, metadataSize }, options);
|
|
368
|
+
} finally {
|
|
369
|
+
zipWriter.pendingEntriesSize -= maximumEntrySize;
|
|
370
|
+
}
|
|
371
|
+
Object.assign(fileEntry, { name, comment, extraField });
|
|
372
|
+
return new Entry(fileEntry);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
376
|
+
const {
|
|
377
|
+
files,
|
|
378
|
+
writer
|
|
379
|
+
} = zipWriter;
|
|
380
|
+
const {
|
|
381
|
+
keepOrder,
|
|
382
|
+
dataDescriptor,
|
|
383
|
+
signal
|
|
384
|
+
} = options;
|
|
385
|
+
const {
|
|
386
|
+
headerInfo
|
|
387
|
+
} = entryInfo;
|
|
388
|
+
const { usdz } = zipWriter.options;
|
|
389
|
+
const previousFileEntry = Array.from(files.values()).pop();
|
|
390
|
+
let fileEntry = {};
|
|
391
|
+
let bufferedWrite;
|
|
392
|
+
let releaseLockWriter;
|
|
393
|
+
let releaseLockCurrentFileEntry;
|
|
394
|
+
let writingBufferedEntryData;
|
|
395
|
+
let writingEntryData;
|
|
396
|
+
let fileWriter;
|
|
397
|
+
let blobPromise;
|
|
398
|
+
files.set(name, fileEntry);
|
|
399
|
+
try {
|
|
400
|
+
let lockPreviousFileEntry;
|
|
401
|
+
if (keepOrder) {
|
|
402
|
+
lockPreviousFileEntry = previousFileEntry && previousFileEntry.lock;
|
|
403
|
+
requestLockCurrentFileEntry();
|
|
404
|
+
}
|
|
405
|
+
if ((options.bufferedWrite || zipWriter.writerLocked || (zipWriter.bufferedWrites && keepOrder) || !dataDescriptor) && !usdz) {
|
|
406
|
+
fileWriter = new TransformStream();
|
|
407
|
+
blobPromise = new Response(fileWriter.readable).blob();
|
|
408
|
+
fileWriter.writable.size = 0;
|
|
409
|
+
bufferedWrite = true;
|
|
410
|
+
zipWriter.bufferedWrites++;
|
|
411
|
+
await initStream(writer);
|
|
412
|
+
} else {
|
|
413
|
+
fileWriter = writer;
|
|
414
|
+
await requestLockWriter();
|
|
415
|
+
}
|
|
416
|
+
await initStream(fileWriter);
|
|
417
|
+
const { writable } = writer;
|
|
418
|
+
let { diskOffset } = writer;
|
|
419
|
+
if (zipWriter.addSplitZipSignature) {
|
|
420
|
+
delete zipWriter.addSplitZipSignature;
|
|
421
|
+
const signatureArray = new Uint8Array(4);
|
|
422
|
+
const signatureArrayView = getDataView(signatureArray);
|
|
423
|
+
setUint32(signatureArrayView, 0, SPLIT_ZIP_FILE_SIGNATURE);
|
|
424
|
+
await writeData(writable, signatureArray);
|
|
425
|
+
zipWriter.offset += 4;
|
|
426
|
+
}
|
|
427
|
+
if (usdz) {
|
|
428
|
+
appendExtraFieldUSDZ(entryInfo, zipWriter.offset - diskOffset);
|
|
429
|
+
}
|
|
430
|
+
if (!bufferedWrite) {
|
|
431
|
+
await lockPreviousFileEntry;
|
|
432
|
+
await skipDiskIfNeeded(writable);
|
|
433
|
+
}
|
|
434
|
+
const { diskNumber } = writer;
|
|
435
|
+
writingEntryData = true;
|
|
436
|
+
fileEntry.diskNumberStart = diskNumber;
|
|
437
|
+
fileEntry = await createFileEntry(reader, fileWriter, fileEntry, entryInfo, zipWriter.config, options);
|
|
438
|
+
writingEntryData = false;
|
|
439
|
+
files.set(name, fileEntry);
|
|
440
|
+
fileEntry.filename = name;
|
|
441
|
+
if (bufferedWrite) {
|
|
442
|
+
await fileWriter.writable.getWriter().close();
|
|
443
|
+
let blob = await blobPromise;
|
|
444
|
+
await lockPreviousFileEntry;
|
|
445
|
+
await requestLockWriter();
|
|
446
|
+
writingBufferedEntryData = true;
|
|
447
|
+
if (!dataDescriptor) {
|
|
448
|
+
blob = await writeExtraHeaderInfo(fileEntry, blob, writable, options);
|
|
449
|
+
}
|
|
450
|
+
await skipDiskIfNeeded(writable);
|
|
451
|
+
fileEntry.diskNumberStart = writer.diskNumber;
|
|
452
|
+
diskOffset = writer.diskOffset;
|
|
453
|
+
await blob.stream().pipeTo(writable, { preventClose: true, preventAbort: true, signal });
|
|
454
|
+
writable.size += blob.size;
|
|
455
|
+
writingBufferedEntryData = false;
|
|
456
|
+
}
|
|
457
|
+
fileEntry.offset = zipWriter.offset - diskOffset;
|
|
458
|
+
if (fileEntry.zip64) {
|
|
459
|
+
setZip64ExtraInfo(fileEntry, options);
|
|
460
|
+
} else if (fileEntry.offset > MAX_32_BITS) {
|
|
461
|
+
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
462
|
+
}
|
|
463
|
+
zipWriter.offset += fileEntry.size;
|
|
464
|
+
return fileEntry;
|
|
465
|
+
} catch (error) {
|
|
466
|
+
if ((bufferedWrite && writingBufferedEntryData) || (!bufferedWrite && writingEntryData)) {
|
|
467
|
+
zipWriter.hasCorruptedEntries = true;
|
|
468
|
+
if (error) {
|
|
469
|
+
try {
|
|
470
|
+
error.corruptedEntry = true;
|
|
471
|
+
} catch (_error) {
|
|
472
|
+
// ignored
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
if (bufferedWrite) {
|
|
476
|
+
zipWriter.offset += fileWriter.writable.size;
|
|
477
|
+
} else {
|
|
478
|
+
zipWriter.offset = fileWriter.writable.size;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
files.delete(name);
|
|
482
|
+
throw error;
|
|
483
|
+
} finally {
|
|
484
|
+
if (bufferedWrite) {
|
|
485
|
+
zipWriter.bufferedWrites--;
|
|
486
|
+
}
|
|
487
|
+
if (releaseLockCurrentFileEntry) {
|
|
488
|
+
releaseLockCurrentFileEntry();
|
|
489
|
+
}
|
|
490
|
+
if (releaseLockWriter) {
|
|
491
|
+
releaseLockWriter();
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
function requestLockCurrentFileEntry() {
|
|
496
|
+
fileEntry.lock = new Promise(resolve => releaseLockCurrentFileEntry = resolve);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
async function requestLockWriter() {
|
|
500
|
+
zipWriter.writerLocked = true;
|
|
501
|
+
const { lockWriter } = zipWriter;
|
|
502
|
+
zipWriter.lockWriter = new Promise(resolve => releaseLockWriter = () => {
|
|
503
|
+
zipWriter.writerLocked = false;
|
|
504
|
+
resolve();
|
|
505
|
+
});
|
|
506
|
+
await lockWriter;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
async function skipDiskIfNeeded(writable) {
|
|
510
|
+
if (getLength(headerInfo.localHeaderArray) > writer.availableSize) {
|
|
511
|
+
writer.availableSize = 0;
|
|
512
|
+
await writeData(writable, new Uint8Array());
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryInfo, config, options) {
|
|
518
|
+
const {
|
|
519
|
+
headerInfo,
|
|
520
|
+
dataDescriptorInfo,
|
|
521
|
+
metadataSize
|
|
522
|
+
} = entryInfo;
|
|
523
|
+
const {
|
|
524
|
+
localHeaderArray,
|
|
525
|
+
headerArray,
|
|
526
|
+
lastModDate,
|
|
527
|
+
rawLastModDate,
|
|
528
|
+
encrypted,
|
|
529
|
+
compressed,
|
|
530
|
+
version,
|
|
531
|
+
compressionMethod,
|
|
532
|
+
rawExtraFieldExtendedTimestamp,
|
|
533
|
+
extraFieldExtendedTimestampFlag,
|
|
534
|
+
rawExtraFieldNTFS,
|
|
535
|
+
rawExtraFieldAES
|
|
536
|
+
} = headerInfo;
|
|
537
|
+
const { dataDescriptorArray } = dataDescriptorInfo;
|
|
538
|
+
const {
|
|
539
|
+
rawFilename,
|
|
540
|
+
lastAccessDate,
|
|
541
|
+
creationDate,
|
|
542
|
+
password,
|
|
543
|
+
rawPassword,
|
|
544
|
+
level,
|
|
545
|
+
zip64,
|
|
546
|
+
zip64UncompressedSize,
|
|
547
|
+
zip64CompressedSize,
|
|
548
|
+
zip64Offset,
|
|
549
|
+
zip64DiskNumberStart,
|
|
550
|
+
zipCrypto,
|
|
551
|
+
dataDescriptor,
|
|
552
|
+
directory,
|
|
553
|
+
versionMadeBy,
|
|
554
|
+
rawComment,
|
|
555
|
+
rawExtraField,
|
|
556
|
+
useWebWorkers,
|
|
557
|
+
onstart,
|
|
558
|
+
onprogress,
|
|
559
|
+
onend,
|
|
560
|
+
signal,
|
|
561
|
+
encryptionStrength,
|
|
562
|
+
extendedTimestamp,
|
|
563
|
+
msDosCompatible,
|
|
564
|
+
internalFileAttribute,
|
|
565
|
+
externalFileAttribute,
|
|
566
|
+
useCompressionStream
|
|
567
|
+
} = options;
|
|
568
|
+
const fileEntry = {
|
|
569
|
+
lock,
|
|
570
|
+
versionMadeBy,
|
|
571
|
+
zip64,
|
|
572
|
+
directory: Boolean(directory),
|
|
573
|
+
filenameUTF8: true,
|
|
574
|
+
rawFilename,
|
|
575
|
+
commentUTF8: true,
|
|
576
|
+
rawComment,
|
|
577
|
+
rawExtraFieldExtendedTimestamp,
|
|
578
|
+
rawExtraFieldNTFS,
|
|
579
|
+
rawExtraFieldAES,
|
|
580
|
+
rawExtraField,
|
|
581
|
+
extendedTimestamp,
|
|
582
|
+
msDosCompatible,
|
|
583
|
+
internalFileAttribute,
|
|
584
|
+
externalFileAttribute,
|
|
585
|
+
diskNumberStart
|
|
586
|
+
};
|
|
587
|
+
let compressedSize = 0;
|
|
588
|
+
let uncompressedSize = 0;
|
|
589
|
+
let signature;
|
|
590
|
+
const { writable } = writer;
|
|
591
|
+
if (reader) {
|
|
592
|
+
reader.chunkSize = getChunkSize(config);
|
|
593
|
+
await writeData(writable, localHeaderArray);
|
|
594
|
+
const readable = reader.readable;
|
|
595
|
+
const size = readable.size = reader.size;
|
|
596
|
+
const workerOptions = {
|
|
597
|
+
options: {
|
|
598
|
+
codecType: CODEC_DEFLATE,
|
|
599
|
+
level,
|
|
600
|
+
rawPassword,
|
|
601
|
+
password,
|
|
602
|
+
encryptionStrength,
|
|
603
|
+
zipCrypto: encrypted && zipCrypto,
|
|
604
|
+
passwordVerification: encrypted && zipCrypto && (rawLastModDate >> 8) & 0xFF,
|
|
605
|
+
signed: true,
|
|
606
|
+
compressed,
|
|
607
|
+
encrypted,
|
|
608
|
+
useWebWorkers,
|
|
609
|
+
useCompressionStream,
|
|
610
|
+
transferStreams: false
|
|
611
|
+
},
|
|
612
|
+
config,
|
|
613
|
+
streamOptions: { signal, size, onstart, onprogress, onend }
|
|
614
|
+
};
|
|
615
|
+
const result = await runWorker({ readable, writable }, workerOptions);
|
|
616
|
+
uncompressedSize = result.inputSize;
|
|
617
|
+
compressedSize = result.outputSize;
|
|
618
|
+
signature = result.signature;
|
|
619
|
+
writable.size += uncompressedSize;
|
|
620
|
+
} else {
|
|
621
|
+
await writeData(writable, localHeaderArray);
|
|
622
|
+
}
|
|
623
|
+
let rawExtraFieldZip64;
|
|
624
|
+
if (zip64) {
|
|
625
|
+
let rawExtraFieldZip64Length = 4;
|
|
626
|
+
if (zip64UncompressedSize) {
|
|
627
|
+
rawExtraFieldZip64Length += 8;
|
|
628
|
+
}
|
|
629
|
+
if (zip64CompressedSize) {
|
|
630
|
+
rawExtraFieldZip64Length += 8;
|
|
631
|
+
}
|
|
632
|
+
if (zip64Offset) {
|
|
633
|
+
rawExtraFieldZip64Length += 8;
|
|
634
|
+
}
|
|
635
|
+
if (zip64DiskNumberStart) {
|
|
636
|
+
rawExtraFieldZip64Length += 4;
|
|
637
|
+
}
|
|
638
|
+
rawExtraFieldZip64 = new Uint8Array(rawExtraFieldZip64Length);
|
|
639
|
+
} else {
|
|
640
|
+
rawExtraFieldZip64 = new Uint8Array();
|
|
641
|
+
}
|
|
642
|
+
setEntryInfo({
|
|
643
|
+
signature,
|
|
644
|
+
rawExtraFieldZip64,
|
|
645
|
+
compressedSize,
|
|
646
|
+
uncompressedSize,
|
|
647
|
+
headerInfo,
|
|
648
|
+
dataDescriptorInfo
|
|
649
|
+
}, options);
|
|
650
|
+
if (dataDescriptor) {
|
|
651
|
+
await writeData(writable, dataDescriptorArray);
|
|
652
|
+
}
|
|
653
|
+
Object.assign(fileEntry, {
|
|
654
|
+
uncompressedSize,
|
|
655
|
+
compressedSize,
|
|
656
|
+
lastModDate,
|
|
657
|
+
rawLastModDate,
|
|
658
|
+
creationDate,
|
|
659
|
+
lastAccessDate,
|
|
660
|
+
encrypted,
|
|
661
|
+
size: metadataSize + compressedSize,
|
|
662
|
+
compressionMethod,
|
|
663
|
+
version,
|
|
664
|
+
headerArray,
|
|
665
|
+
signature,
|
|
666
|
+
rawExtraFieldZip64,
|
|
667
|
+
extraFieldExtendedTimestampFlag,
|
|
668
|
+
zip64UncompressedSize,
|
|
669
|
+
zip64CompressedSize,
|
|
670
|
+
zip64Offset,
|
|
671
|
+
zip64DiskNumberStart
|
|
672
|
+
});
|
|
673
|
+
return fileEntry;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
function getHeaderInfo(options) {
|
|
677
|
+
const {
|
|
678
|
+
rawFilename,
|
|
679
|
+
lastModDate,
|
|
680
|
+
lastAccessDate,
|
|
681
|
+
creationDate,
|
|
682
|
+
rawPassword,
|
|
683
|
+
password,
|
|
684
|
+
level,
|
|
685
|
+
zip64,
|
|
686
|
+
zipCrypto,
|
|
687
|
+
dataDescriptor,
|
|
688
|
+
directory,
|
|
689
|
+
rawExtraField,
|
|
690
|
+
encryptionStrength,
|
|
691
|
+
extendedTimestamp
|
|
692
|
+
} = options;
|
|
693
|
+
const compressed = level !== 0 && !directory;
|
|
694
|
+
const encrypted = Boolean((password && getLength(password)) || (rawPassword && getLength(rawPassword)));
|
|
695
|
+
let version = options.version;
|
|
696
|
+
let rawExtraFieldAES;
|
|
697
|
+
if (encrypted && !zipCrypto) {
|
|
698
|
+
rawExtraFieldAES = new Uint8Array(getLength(EXTRAFIELD_DATA_AES) + 2);
|
|
699
|
+
const extraFieldAESView = getDataView(rawExtraFieldAES);
|
|
700
|
+
setUint16(extraFieldAESView, 0, EXTRAFIELD_TYPE_AES);
|
|
701
|
+
arraySet(rawExtraFieldAES, EXTRAFIELD_DATA_AES, 2);
|
|
702
|
+
setUint8(extraFieldAESView, 8, encryptionStrength);
|
|
703
|
+
} else {
|
|
704
|
+
rawExtraFieldAES = new Uint8Array();
|
|
705
|
+
}
|
|
706
|
+
let rawExtraFieldNTFS;
|
|
707
|
+
let rawExtraFieldExtendedTimestamp;
|
|
708
|
+
let extraFieldExtendedTimestampFlag;
|
|
709
|
+
if (extendedTimestamp) {
|
|
710
|
+
rawExtraFieldExtendedTimestamp = new Uint8Array(9 + (lastAccessDate ? 4 : 0) + (creationDate ? 4 : 0));
|
|
711
|
+
const extraFieldExtendedTimestampView = getDataView(rawExtraFieldExtendedTimestamp);
|
|
712
|
+
setUint16(extraFieldExtendedTimestampView, 0, EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
713
|
+
setUint16(extraFieldExtendedTimestampView, 2, getLength(rawExtraFieldExtendedTimestamp) - 4);
|
|
714
|
+
extraFieldExtendedTimestampFlag = 0x1 + (lastAccessDate ? 0x2 : 0) + (creationDate ? 0x4 : 0);
|
|
715
|
+
setUint8(extraFieldExtendedTimestampView, 4, extraFieldExtendedTimestampFlag);
|
|
716
|
+
let offset = 5;
|
|
717
|
+
setUint32(extraFieldExtendedTimestampView, offset, Math.floor(lastModDate.getTime() / 1000));
|
|
718
|
+
offset += 4;
|
|
719
|
+
if (lastAccessDate) {
|
|
720
|
+
setUint32(extraFieldExtendedTimestampView, offset, Math.floor(lastAccessDate.getTime() / 1000));
|
|
721
|
+
offset += 4;
|
|
722
|
+
}
|
|
723
|
+
if (creationDate) {
|
|
724
|
+
setUint32(extraFieldExtendedTimestampView, offset, Math.floor(creationDate.getTime() / 1000));
|
|
725
|
+
}
|
|
726
|
+
try {
|
|
727
|
+
rawExtraFieldNTFS = new Uint8Array(36);
|
|
728
|
+
const extraFieldNTFSView = getDataView(rawExtraFieldNTFS);
|
|
729
|
+
const lastModTimeNTFS = getTimeNTFS(lastModDate);
|
|
730
|
+
setUint16(extraFieldNTFSView, 0, EXTRAFIELD_TYPE_NTFS);
|
|
731
|
+
setUint16(extraFieldNTFSView, 2, 32);
|
|
732
|
+
setUint16(extraFieldNTFSView, 8, EXTRAFIELD_TYPE_NTFS_TAG1);
|
|
733
|
+
setUint16(extraFieldNTFSView, 10, 24);
|
|
734
|
+
setBigUint64(extraFieldNTFSView, 12, lastModTimeNTFS);
|
|
735
|
+
setBigUint64(extraFieldNTFSView, 20, getTimeNTFS(lastAccessDate) || lastModTimeNTFS);
|
|
736
|
+
setBigUint64(extraFieldNTFSView, 28, getTimeNTFS(creationDate) || lastModTimeNTFS);
|
|
737
|
+
} catch (_error) {
|
|
738
|
+
rawExtraFieldNTFS = new Uint8Array();
|
|
739
|
+
}
|
|
740
|
+
} else {
|
|
741
|
+
rawExtraFieldNTFS = rawExtraFieldExtendedTimestamp = new Uint8Array();
|
|
742
|
+
}
|
|
743
|
+
let bitFlag = BITFLAG_LANG_ENCODING_FLAG;
|
|
744
|
+
if (dataDescriptor) {
|
|
745
|
+
bitFlag = bitFlag | BITFLAG_DATA_DESCRIPTOR;
|
|
746
|
+
}
|
|
747
|
+
let compressionMethod = COMPRESSION_METHOD_STORE;
|
|
748
|
+
if (compressed) {
|
|
749
|
+
compressionMethod = COMPRESSION_METHOD_DEFLATE;
|
|
750
|
+
}
|
|
751
|
+
if (zip64) {
|
|
752
|
+
version = version > VERSION_ZIP64 ? version : VERSION_ZIP64;
|
|
753
|
+
}
|
|
754
|
+
if (encrypted) {
|
|
755
|
+
bitFlag = bitFlag | BITFLAG_ENCRYPTED;
|
|
756
|
+
if (!zipCrypto) {
|
|
757
|
+
version = version > VERSION_AES ? version : VERSION_AES;
|
|
758
|
+
compressionMethod = COMPRESSION_METHOD_AES;
|
|
759
|
+
if (compressed) {
|
|
760
|
+
rawExtraFieldAES[9] = COMPRESSION_METHOD_DEFLATE;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
const headerArray = new Uint8Array(26);
|
|
765
|
+
const headerView = getDataView(headerArray);
|
|
766
|
+
setUint16(headerView, 0, version);
|
|
767
|
+
setUint16(headerView, 2, bitFlag);
|
|
768
|
+
setUint16(headerView, 4, compressionMethod);
|
|
769
|
+
const dateArray = new Uint32Array(1);
|
|
770
|
+
const dateView = getDataView(dateArray);
|
|
771
|
+
let lastModDateMsDos;
|
|
772
|
+
if (lastModDate < MIN_DATE) {
|
|
773
|
+
lastModDateMsDos = MIN_DATE;
|
|
774
|
+
} else if (lastModDate > MAX_DATE) {
|
|
775
|
+
lastModDateMsDos = MAX_DATE;
|
|
776
|
+
} else {
|
|
777
|
+
lastModDateMsDos = lastModDate;
|
|
778
|
+
}
|
|
779
|
+
setUint16(dateView, 0, (((lastModDateMsDos.getHours() << 6) | lastModDateMsDos.getMinutes()) << 5) | lastModDateMsDos.getSeconds() / 2);
|
|
780
|
+
setUint16(dateView, 2, ((((lastModDateMsDos.getFullYear() - 1980) << 4) | (lastModDateMsDos.getMonth() + 1)) << 5) | lastModDateMsDos.getDate());
|
|
781
|
+
const rawLastModDate = dateArray[0];
|
|
782
|
+
setUint32(headerView, 6, rawLastModDate);
|
|
783
|
+
setUint16(headerView, 22, getLength(rawFilename));
|
|
784
|
+
const extraFieldLength = getLength(rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
|
|
785
|
+
setUint16(headerView, 24, extraFieldLength);
|
|
786
|
+
const localHeaderArray = new Uint8Array(30 + getLength(rawFilename) + extraFieldLength);
|
|
787
|
+
const localHeaderView = getDataView(localHeaderArray);
|
|
788
|
+
setUint32(localHeaderView, 0, LOCAL_FILE_HEADER_SIGNATURE);
|
|
789
|
+
arraySet(localHeaderArray, headerArray, 4);
|
|
790
|
+
arraySet(localHeaderArray, rawFilename, 30);
|
|
791
|
+
arraySet(localHeaderArray, rawExtraFieldAES, 30 + getLength(rawFilename));
|
|
792
|
+
arraySet(localHeaderArray, rawExtraFieldExtendedTimestamp, 30 + getLength(rawFilename, rawExtraFieldAES));
|
|
793
|
+
arraySet(localHeaderArray, rawExtraFieldNTFS, 30 + getLength(rawFilename, rawExtraFieldAES, rawExtraFieldExtendedTimestamp));
|
|
794
|
+
arraySet(localHeaderArray, rawExtraField, 30 + getLength(rawFilename, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS));
|
|
795
|
+
return {
|
|
796
|
+
localHeaderArray,
|
|
797
|
+
headerArray,
|
|
798
|
+
headerView,
|
|
799
|
+
lastModDate,
|
|
800
|
+
rawLastModDate,
|
|
801
|
+
encrypted,
|
|
802
|
+
compressed,
|
|
803
|
+
version,
|
|
804
|
+
compressionMethod,
|
|
805
|
+
extraFieldExtendedTimestampFlag,
|
|
806
|
+
rawExtraFieldExtendedTimestamp,
|
|
807
|
+
rawExtraFieldNTFS,
|
|
808
|
+
rawExtraFieldAES,
|
|
809
|
+
extraFieldLength
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
function appendExtraFieldUSDZ(entryInfo, zipWriterOffset) {
|
|
814
|
+
const { headerInfo } = entryInfo;
|
|
815
|
+
let { localHeaderArray, extraFieldLength } = headerInfo;
|
|
816
|
+
let localHeaderArrayView = getDataView(localHeaderArray);
|
|
817
|
+
let extraBytesLength = 64 - ((zipWriterOffset + getLength(localHeaderArray)) % 64);
|
|
818
|
+
if (extraBytesLength < 4) {
|
|
819
|
+
extraBytesLength += 64;
|
|
820
|
+
}
|
|
821
|
+
const rawExtraFieldUSDZ = new Uint8Array(extraBytesLength);
|
|
822
|
+
const extraFieldUSDZView = getDataView(rawExtraFieldUSDZ);
|
|
823
|
+
setUint16(extraFieldUSDZView, 0, EXTRAFIELD_TYPE_USDZ);
|
|
824
|
+
setUint16(extraFieldUSDZView, 2, extraBytesLength - 2);
|
|
825
|
+
const previousLocalHeaderArray = localHeaderArray;
|
|
826
|
+
headerInfo.localHeaderArray = localHeaderArray = new Uint8Array(getLength(previousLocalHeaderArray) + extraBytesLength);
|
|
827
|
+
arraySet(localHeaderArray, previousLocalHeaderArray);
|
|
828
|
+
arraySet(localHeaderArray, rawExtraFieldUSDZ, getLength(previousLocalHeaderArray));
|
|
829
|
+
localHeaderArrayView = getDataView(localHeaderArray);
|
|
830
|
+
setUint16(localHeaderArrayView, 28, extraFieldLength + extraBytesLength);
|
|
831
|
+
entryInfo.metadataSize += extraBytesLength;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
function getDataDescriptorInfo(options) {
|
|
835
|
+
const {
|
|
836
|
+
zip64,
|
|
837
|
+
dataDescriptor,
|
|
838
|
+
dataDescriptorSignature
|
|
839
|
+
} = options;
|
|
840
|
+
let dataDescriptorArray = new Uint8Array();
|
|
841
|
+
let dataDescriptorView, dataDescriptorOffset = 0;
|
|
842
|
+
if (dataDescriptor) {
|
|
843
|
+
dataDescriptorArray = new Uint8Array(zip64 ? (dataDescriptorSignature ? 24 : 20) : (dataDescriptorSignature ? 16 : 12));
|
|
844
|
+
dataDescriptorView = getDataView(dataDescriptorArray);
|
|
845
|
+
if (dataDescriptorSignature) {
|
|
846
|
+
dataDescriptorOffset = 4;
|
|
847
|
+
setUint32(dataDescriptorView, 0, DATA_DESCRIPTOR_RECORD_SIGNATURE);
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
return {
|
|
851
|
+
dataDescriptorArray,
|
|
852
|
+
dataDescriptorView,
|
|
853
|
+
dataDescriptorOffset
|
|
854
|
+
};
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
function setEntryInfo(entryInfo, options) {
|
|
858
|
+
const {
|
|
859
|
+
signature,
|
|
860
|
+
rawExtraFieldZip64,
|
|
861
|
+
compressedSize,
|
|
862
|
+
uncompressedSize,
|
|
863
|
+
headerInfo,
|
|
864
|
+
dataDescriptorInfo
|
|
865
|
+
} = entryInfo;
|
|
866
|
+
const {
|
|
867
|
+
headerView,
|
|
868
|
+
encrypted
|
|
869
|
+
} = headerInfo;
|
|
870
|
+
const {
|
|
871
|
+
dataDescriptorView,
|
|
872
|
+
dataDescriptorOffset
|
|
873
|
+
} = dataDescriptorInfo;
|
|
874
|
+
const {
|
|
875
|
+
zip64,
|
|
876
|
+
zip64UncompressedSize,
|
|
877
|
+
zip64CompressedSize,
|
|
878
|
+
zipCrypto,
|
|
879
|
+
dataDescriptor
|
|
880
|
+
} = options;
|
|
881
|
+
if ((!encrypted || zipCrypto) && signature !== UNDEFINED_VALUE) {
|
|
882
|
+
setUint32(headerView, 10, signature);
|
|
883
|
+
if (dataDescriptor) {
|
|
884
|
+
setUint32(dataDescriptorView, dataDescriptorOffset, signature);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
if (zip64) {
|
|
888
|
+
const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
|
|
889
|
+
setUint16(rawExtraFieldZip64View, 0, EXTRAFIELD_TYPE_ZIP64);
|
|
890
|
+
setUint16(rawExtraFieldZip64View, 2, getLength(rawExtraFieldZip64) - 4);
|
|
891
|
+
let rawExtraFieldZip64Offset = 4;
|
|
892
|
+
if (zip64UncompressedSize) {
|
|
893
|
+
setUint32(headerView, 18, MAX_32_BITS);
|
|
894
|
+
setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(uncompressedSize));
|
|
895
|
+
rawExtraFieldZip64Offset += 8;
|
|
896
|
+
}
|
|
897
|
+
if (zip64CompressedSize) {
|
|
898
|
+
setUint32(headerView, 14, MAX_32_BITS);
|
|
899
|
+
setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(compressedSize));
|
|
900
|
+
}
|
|
901
|
+
if (dataDescriptor) {
|
|
902
|
+
setBigUint64(dataDescriptorView, dataDescriptorOffset + 4, BigInt(compressedSize));
|
|
903
|
+
setBigUint64(dataDescriptorView, dataDescriptorOffset + 12, BigInt(uncompressedSize));
|
|
904
|
+
}
|
|
905
|
+
} else {
|
|
906
|
+
setUint32(headerView, 14, compressedSize);
|
|
907
|
+
setUint32(headerView, 18, uncompressedSize);
|
|
908
|
+
if (dataDescriptor) {
|
|
909
|
+
setUint32(dataDescriptorView, dataDescriptorOffset + 4, compressedSize);
|
|
910
|
+
setUint32(dataDescriptorView, dataDescriptorOffset + 8, uncompressedSize);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
async function writeExtraHeaderInfo(fileEntry, entryData, writable, { zipCrypto }) {
|
|
916
|
+
let arrayBuffer;
|
|
917
|
+
arrayBuffer = await entryData.slice(0, 26).arrayBuffer();
|
|
918
|
+
if (arrayBuffer.byteLength != 26) {
|
|
919
|
+
arrayBuffer = arrayBuffer.slice(0, 26);
|
|
920
|
+
}
|
|
921
|
+
const arrayBufferView = new DataView(arrayBuffer);
|
|
922
|
+
if (!fileEntry.encrypted || zipCrypto) {
|
|
923
|
+
setUint32(arrayBufferView, 14, fileEntry.signature);
|
|
924
|
+
}
|
|
925
|
+
if (fileEntry.zip64) {
|
|
926
|
+
setUint32(arrayBufferView, 18, MAX_32_BITS);
|
|
927
|
+
setUint32(arrayBufferView, 22, MAX_32_BITS);
|
|
928
|
+
} else {
|
|
929
|
+
setUint32(arrayBufferView, 18, fileEntry.compressedSize);
|
|
930
|
+
setUint32(arrayBufferView, 22, fileEntry.uncompressedSize);
|
|
931
|
+
}
|
|
932
|
+
await writeData(writable, new Uint8Array(arrayBuffer));
|
|
933
|
+
return entryData.slice(arrayBuffer.byteLength);
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
function setZip64ExtraInfo(fileEntry, options) {
|
|
937
|
+
const { rawExtraFieldZip64, offset, diskNumberStart } = fileEntry;
|
|
938
|
+
const { zip64UncompressedSize, zip64CompressedSize, zip64Offset, zip64DiskNumberStart } = options;
|
|
939
|
+
const rawExtraFieldZip64View = getDataView(rawExtraFieldZip64);
|
|
940
|
+
let rawExtraFieldZip64Offset = 4;
|
|
941
|
+
if (zip64UncompressedSize) {
|
|
942
|
+
rawExtraFieldZip64Offset += 8;
|
|
943
|
+
}
|
|
944
|
+
if (zip64CompressedSize) {
|
|
945
|
+
rawExtraFieldZip64Offset += 8;
|
|
946
|
+
}
|
|
947
|
+
if (zip64Offset) {
|
|
948
|
+
setBigUint64(rawExtraFieldZip64View, rawExtraFieldZip64Offset, BigInt(offset));
|
|
949
|
+
rawExtraFieldZip64Offset += 8;
|
|
950
|
+
}
|
|
951
|
+
if (zip64DiskNumberStart) {
|
|
952
|
+
setUint32(rawExtraFieldZip64View, rawExtraFieldZip64Offset, diskNumberStart);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
async function closeFile(zipWriter, comment, options) {
|
|
957
|
+
const { files, writer } = zipWriter;
|
|
958
|
+
const { diskOffset, writable } = writer;
|
|
959
|
+
let { diskNumber } = writer;
|
|
960
|
+
let offset = 0;
|
|
961
|
+
let directoryDataLength = 0;
|
|
962
|
+
let directoryOffset = zipWriter.offset - diskOffset;
|
|
963
|
+
let filesLength = files.size;
|
|
964
|
+
for (const [, fileEntry] of files) {
|
|
965
|
+
const {
|
|
966
|
+
rawFilename,
|
|
967
|
+
rawExtraFieldZip64,
|
|
968
|
+
rawExtraFieldAES,
|
|
969
|
+
rawComment,
|
|
970
|
+
rawExtraFieldNTFS,
|
|
971
|
+
rawExtraField,
|
|
972
|
+
extendedTimestamp,
|
|
973
|
+
extraFieldExtendedTimestampFlag,
|
|
974
|
+
lastModDate
|
|
975
|
+
} = fileEntry;
|
|
976
|
+
let rawExtraFieldTimestamp;
|
|
977
|
+
if (extendedTimestamp) {
|
|
978
|
+
rawExtraFieldTimestamp = new Uint8Array(9);
|
|
979
|
+
const extraFieldExtendedTimestampView = getDataView(rawExtraFieldTimestamp);
|
|
980
|
+
setUint16(extraFieldExtendedTimestampView, 0, EXTRAFIELD_TYPE_EXTENDED_TIMESTAMP);
|
|
981
|
+
setUint16(extraFieldExtendedTimestampView, 2, 5);
|
|
982
|
+
setUint8(extraFieldExtendedTimestampView, 4, extraFieldExtendedTimestampFlag);
|
|
983
|
+
setUint32(extraFieldExtendedTimestampView, 5, Math.floor(lastModDate.getTime() / 1000));
|
|
984
|
+
} else {
|
|
985
|
+
rawExtraFieldTimestamp = new Uint8Array();
|
|
986
|
+
}
|
|
987
|
+
fileEntry.rawExtraFieldCDExtendedTimestamp = rawExtraFieldTimestamp;
|
|
988
|
+
directoryDataLength += 46 +
|
|
989
|
+
getLength(
|
|
990
|
+
rawFilename,
|
|
991
|
+
rawComment,
|
|
992
|
+
rawExtraFieldZip64,
|
|
993
|
+
rawExtraFieldAES,
|
|
994
|
+
rawExtraFieldNTFS,
|
|
995
|
+
rawExtraFieldTimestamp,
|
|
996
|
+
rawExtraField);
|
|
997
|
+
}
|
|
998
|
+
const directoryArray = new Uint8Array(directoryDataLength);
|
|
999
|
+
const directoryView = getDataView(directoryArray);
|
|
1000
|
+
await initStream(writer);
|
|
1001
|
+
let directoryDiskOffset = 0;
|
|
1002
|
+
for (const [indexFileEntry, fileEntry] of Array.from(files.values()).entries()) {
|
|
1003
|
+
const {
|
|
1004
|
+
offset: fileEntryOffset,
|
|
1005
|
+
rawFilename,
|
|
1006
|
+
rawExtraFieldZip64,
|
|
1007
|
+
rawExtraFieldAES,
|
|
1008
|
+
rawExtraFieldCDExtendedTimestamp,
|
|
1009
|
+
rawExtraFieldNTFS,
|
|
1010
|
+
rawExtraField,
|
|
1011
|
+
rawComment,
|
|
1012
|
+
versionMadeBy,
|
|
1013
|
+
headerArray,
|
|
1014
|
+
directory,
|
|
1015
|
+
zip64,
|
|
1016
|
+
zip64UncompressedSize,
|
|
1017
|
+
zip64CompressedSize,
|
|
1018
|
+
zip64DiskNumberStart,
|
|
1019
|
+
zip64Offset,
|
|
1020
|
+
msDosCompatible,
|
|
1021
|
+
internalFileAttribute,
|
|
1022
|
+
externalFileAttribute,
|
|
1023
|
+
diskNumberStart,
|
|
1024
|
+
uncompressedSize,
|
|
1025
|
+
compressedSize
|
|
1026
|
+
} = fileEntry;
|
|
1027
|
+
const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldCDExtendedTimestamp, rawExtraFieldNTFS, rawExtraField);
|
|
1028
|
+
setUint32(directoryView, offset, CENTRAL_FILE_HEADER_SIGNATURE);
|
|
1029
|
+
setUint16(directoryView, offset + 4, versionMadeBy);
|
|
1030
|
+
const headerView = getDataView(headerArray);
|
|
1031
|
+
if (!zip64UncompressedSize) {
|
|
1032
|
+
setUint32(headerView, 18, uncompressedSize);
|
|
1033
|
+
}
|
|
1034
|
+
if (!zip64CompressedSize) {
|
|
1035
|
+
setUint32(headerView, 14, compressedSize);
|
|
1036
|
+
}
|
|
1037
|
+
arraySet(directoryArray, headerArray, offset + 6);
|
|
1038
|
+
setUint16(directoryView, offset + 30, extraFieldLength);
|
|
1039
|
+
setUint16(directoryView, offset + 32, getLength(rawComment));
|
|
1040
|
+
setUint16(directoryView, offset + 34, zip64 && zip64DiskNumberStart ? MAX_16_BITS : diskNumberStart);
|
|
1041
|
+
setUint16(directoryView, offset + 36, internalFileAttribute);
|
|
1042
|
+
if (externalFileAttribute) {
|
|
1043
|
+
setUint32(directoryView, offset + 38, externalFileAttribute);
|
|
1044
|
+
} else if (directory && msDosCompatible) {
|
|
1045
|
+
setUint8(directoryView, offset + 38, FILE_ATTR_MSDOS_DIR_MASK);
|
|
1046
|
+
}
|
|
1047
|
+
setUint32(directoryView, offset + 42, zip64 && zip64Offset ? MAX_32_BITS : fileEntryOffset);
|
|
1048
|
+
arraySet(directoryArray, rawFilename, offset + 46);
|
|
1049
|
+
arraySet(directoryArray, rawExtraFieldZip64, offset + 46 + getLength(rawFilename));
|
|
1050
|
+
arraySet(directoryArray, rawExtraFieldAES, offset + 46 + getLength(rawFilename, rawExtraFieldZip64));
|
|
1051
|
+
arraySet(directoryArray, rawExtraFieldCDExtendedTimestamp, offset + 46 + getLength(rawFilename, rawExtraFieldZip64, rawExtraFieldAES));
|
|
1052
|
+
arraySet(directoryArray, rawExtraFieldNTFS, offset + 46 + getLength(rawFilename, rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldCDExtendedTimestamp));
|
|
1053
|
+
arraySet(directoryArray, rawExtraField, offset + 46 + getLength(rawFilename, rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldCDExtendedTimestamp, rawExtraFieldNTFS));
|
|
1054
|
+
arraySet(directoryArray, rawComment, offset + 46 + getLength(rawFilename) + extraFieldLength);
|
|
1055
|
+
const directoryEntryLength = 46 + getLength(rawFilename, rawComment) + extraFieldLength;
|
|
1056
|
+
if (offset - directoryDiskOffset > writer.availableSize) {
|
|
1057
|
+
writer.availableSize = 0;
|
|
1058
|
+
await writeData(writable, directoryArray.slice(directoryDiskOffset, offset));
|
|
1059
|
+
directoryDiskOffset = offset;
|
|
1060
|
+
}
|
|
1061
|
+
offset += directoryEntryLength;
|
|
1062
|
+
if (options.onprogress) {
|
|
1063
|
+
try {
|
|
1064
|
+
await options.onprogress(indexFileEntry + 1, files.size, new Entry(fileEntry));
|
|
1065
|
+
} catch (_error) {
|
|
1066
|
+
// ignored
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
await writeData(writable, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
|
|
1071
|
+
let lastDiskNumber = writer.diskNumber;
|
|
1072
|
+
const { availableSize } = writer;
|
|
1073
|
+
if (availableSize < END_OF_CENTRAL_DIR_LENGTH) {
|
|
1074
|
+
lastDiskNumber++;
|
|
1075
|
+
}
|
|
1076
|
+
let zip64 = getOptionValue(zipWriter, options, "zip64");
|
|
1077
|
+
if (directoryOffset > MAX_32_BITS || directoryDataLength > MAX_32_BITS || filesLength > MAX_16_BITS || lastDiskNumber > MAX_16_BITS) {
|
|
1078
|
+
if (zip64 === false) {
|
|
1079
|
+
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
1080
|
+
} else {
|
|
1081
|
+
zip64 = true;
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
const endOfdirectoryArray = new Uint8Array(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
|
|
1085
|
+
const endOfdirectoryView = getDataView(endOfdirectoryArray);
|
|
1086
|
+
offset = 0;
|
|
1087
|
+
if (zip64) {
|
|
1088
|
+
setUint32(endOfdirectoryView, 0, ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
|
|
1089
|
+
setBigUint64(endOfdirectoryView, 4, BigInt(44));
|
|
1090
|
+
setUint16(endOfdirectoryView, 12, 45);
|
|
1091
|
+
setUint16(endOfdirectoryView, 14, 45);
|
|
1092
|
+
setUint32(endOfdirectoryView, 16, lastDiskNumber);
|
|
1093
|
+
setUint32(endOfdirectoryView, 20, diskNumber);
|
|
1094
|
+
setBigUint64(endOfdirectoryView, 24, BigInt(filesLength));
|
|
1095
|
+
setBigUint64(endOfdirectoryView, 32, BigInt(filesLength));
|
|
1096
|
+
setBigUint64(endOfdirectoryView, 40, BigInt(directoryDataLength));
|
|
1097
|
+
setBigUint64(endOfdirectoryView, 48, BigInt(directoryOffset));
|
|
1098
|
+
setUint32(endOfdirectoryView, 56, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
|
|
1099
|
+
setBigUint64(endOfdirectoryView, 64, BigInt(directoryOffset) + BigInt(directoryDataLength));
|
|
1100
|
+
setUint32(endOfdirectoryView, 72, lastDiskNumber + 1);
|
|
1101
|
+
const supportZip64SplitFile = getOptionValue(zipWriter, options, "supportZip64SplitFile", true);
|
|
1102
|
+
if (supportZip64SplitFile) {
|
|
1103
|
+
lastDiskNumber = MAX_16_BITS;
|
|
1104
|
+
diskNumber = MAX_16_BITS;
|
|
1105
|
+
}
|
|
1106
|
+
filesLength = MAX_16_BITS;
|
|
1107
|
+
directoryOffset = MAX_32_BITS;
|
|
1108
|
+
directoryDataLength = MAX_32_BITS;
|
|
1109
|
+
offset += ZIP64_END_OF_CENTRAL_DIR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH;
|
|
1110
|
+
}
|
|
1111
|
+
setUint32(endOfdirectoryView, offset, END_OF_CENTRAL_DIR_SIGNATURE);
|
|
1112
|
+
setUint16(endOfdirectoryView, offset + 4, lastDiskNumber);
|
|
1113
|
+
setUint16(endOfdirectoryView, offset + 6, diskNumber);
|
|
1114
|
+
setUint16(endOfdirectoryView, offset + 8, filesLength);
|
|
1115
|
+
setUint16(endOfdirectoryView, offset + 10, filesLength);
|
|
1116
|
+
setUint32(endOfdirectoryView, offset + 12, directoryDataLength);
|
|
1117
|
+
setUint32(endOfdirectoryView, offset + 16, directoryOffset);
|
|
1118
|
+
const commentLength = getLength(comment);
|
|
1119
|
+
if (commentLength) {
|
|
1120
|
+
if (commentLength <= MAX_16_BITS) {
|
|
1121
|
+
setUint16(endOfdirectoryView, offset + 20, commentLength);
|
|
1122
|
+
} else {
|
|
1123
|
+
throw new Error(ERR_INVALID_COMMENT);
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
await writeData(writable, endOfdirectoryArray);
|
|
1127
|
+
if (commentLength) {
|
|
1128
|
+
await writeData(writable, comment);
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
async function writeData(writable, array) {
|
|
1133
|
+
const streamWriter = writable.getWriter();
|
|
1134
|
+
try {
|
|
1135
|
+
await streamWriter.ready;
|
|
1136
|
+
writable.size += getLength(array);
|
|
1137
|
+
await streamWriter.write(array);
|
|
1138
|
+
} finally {
|
|
1139
|
+
streamWriter.releaseLock();
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
function getTimeNTFS(date) {
|
|
1144
|
+
if (date) {
|
|
1145
|
+
return ((BigInt(date.getTime()) + BigInt(11644473600000)) * BigInt(10000));
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
function getOptionValue(zipWriter, options, name, defaultValue) {
|
|
1150
|
+
const result = options[name] === UNDEFINED_VALUE ? zipWriter.options[name] : options[name];
|
|
1151
|
+
return result === UNDEFINED_VALUE ? defaultValue : result;
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
function getMaximumCompressedSize(uncompressedSize) {
|
|
1155
|
+
return uncompressedSize + (5 * (Math.floor(uncompressedSize / 16383) + 1));
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
function setUint8(view, offset, value) {
|
|
1159
|
+
view.setUint8(offset, value);
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
function setUint16(view, offset, value) {
|
|
1163
|
+
view.setUint16(offset, value, true);
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
function setUint32(view, offset, value) {
|
|
1167
|
+
view.setUint32(offset, value, true);
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
function setBigUint64(view, offset, value) {
|
|
1171
|
+
view.setBigUint64(offset, value, true);
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
function arraySet(array, typedArray, offset) {
|
|
1175
|
+
array.set(typedArray, offset);
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
function getDataView(array) {
|
|
1179
|
+
return new DataView(array.buffer);
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
function getLength(...arrayLikes) {
|
|
1183
|
+
let result = 0;
|
|
1184
|
+
arrayLikes.forEach(arrayLike => arrayLike && (result += arrayLike.length));
|
|
1185
|
+
return result;
|
|
1186
|
+
}
|