@loaders.gl/zip 4.1.0-alpha.1 → 4.1.0-alpha.11
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/dist/dist.dev.js +875 -64
- package/dist/filesystems/zip-filesystem.d.ts.map +1 -1
- package/dist/filesystems/zip-filesystem.js.map +1 -1
- package/dist/hash-file-utility.d.ts +19 -0
- package/dist/hash-file-utility.d.ts.map +1 -1
- package/dist/hash-file-utility.js +30 -0
- package/dist/hash-file-utility.js.map +1 -1
- package/dist/index.cjs +542 -56
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/tar/header.d.ts.map +1 -1
- package/dist/lib/tar/header.js.map +1 -1
- package/dist/lib/tar/tar.d.ts.map +1 -1
- package/dist/lib/tar/tar.js.map +1 -1
- package/dist/lib/tar/types.d.ts.map +1 -1
- package/dist/lib/tar/types.js.map +1 -1
- package/dist/lib/tar/utils.d.ts.map +1 -1
- package/dist/lib/tar/utils.js.map +1 -1
- package/dist/parse-zip/cd-file-header.d.ts +1 -1
- package/dist/parse-zip/cd-file-header.d.ts.map +1 -1
- package/dist/parse-zip/cd-file-header.js +4 -4
- package/dist/parse-zip/cd-file-header.js.map +1 -1
- package/dist/parse-zip/end-of-central-directory.d.ts +35 -0
- package/dist/parse-zip/end-of-central-directory.d.ts.map +1 -1
- package/dist/parse-zip/end-of-central-directory.js +161 -9
- package/dist/parse-zip/end-of-central-directory.js.map +1 -1
- package/dist/parse-zip/local-file-header.d.ts +16 -0
- package/dist/parse-zip/local-file-header.d.ts.map +1 -1
- package/dist/parse-zip/local-file-header.js +73 -1
- package/dist/parse-zip/local-file-header.js.map +1 -1
- package/dist/parse-zip/search-from-the-end.d.ts.map +1 -1
- package/dist/parse-zip/search-from-the-end.js.map +1 -1
- package/dist/parse-zip/zip-composition.d.ts +38 -0
- package/dist/parse-zip/zip-composition.d.ts.map +1 -0
- package/dist/parse-zip/zip-composition.js +115 -0
- package/dist/parse-zip/zip-composition.js.map +1 -0
- package/dist/parse-zip/zip64-info-generation.d.ts +5 -8
- package/dist/parse-zip/zip64-info-generation.d.ts.map +1 -1
- package/dist/parse-zip/zip64-info-generation.js +6 -3
- package/dist/parse-zip/zip64-info-generation.js.map +1 -1
- package/dist/tar-builder.d.ts.map +1 -1
- package/dist/tar-builder.js.map +1 -1
- package/dist/zip-loader.d.ts.map +1 -1
- package/dist/zip-loader.js +1 -1
- package/dist/zip-loader.js.map +1 -1
- package/dist/zip-writer.d.ts +2 -2
- package/dist/zip-writer.d.ts.map +1 -1
- package/dist/zip-writer.js +22 -7
- package/dist/zip-writer.js.map +1 -1
- package/package.json +7 -7
- package/src/filesystems/zip-filesystem.ts +2 -1
- package/src/hash-file-utility.ts +84 -3
- package/src/index.ts +6 -3
- package/src/lib/tar/header.ts +2 -1
- package/src/lib/tar/tar.ts +2 -1
- package/src/lib/tar/types.ts +2 -1
- package/src/lib/tar/utils.ts +2 -1
- package/src/parse-zip/cd-file-header.ts +8 -6
- package/src/parse-zip/end-of-central-directory.ts +338 -10
- package/src/parse-zip/local-file-header.ts +128 -2
- package/src/parse-zip/search-from-the-end.ts +2 -1
- package/src/parse-zip/zip-composition.ts +235 -0
- package/src/parse-zip/zip64-info-generation.ts +21 -5
- package/src/tar-builder.ts +2 -1
- package/src/zip-loader.ts +2 -1
- package/src/zip-writer.ts +24 -10
package/dist/index.cjs
CHANGED
|
@@ -35,7 +35,11 @@ __export(src_exports, {
|
|
|
35
35
|
ZipFileSystem: () => ZipFileSystem,
|
|
36
36
|
ZipLoader: () => ZipLoader,
|
|
37
37
|
ZipWriter: () => ZipWriter,
|
|
38
|
+
addOneFile: () => addOneFile,
|
|
39
|
+
composeHashFile: () => composeHashFile,
|
|
40
|
+
createZip: () => createZip,
|
|
38
41
|
generateCDHeader: () => generateCDHeader,
|
|
42
|
+
generateLocalHeader: () => generateLocalHeader,
|
|
39
43
|
localHeaderSignature: () => signature3,
|
|
40
44
|
makeHashTableFromZipHeaders: () => makeHashTableFromZipHeaders,
|
|
41
45
|
makeZipCDHeaderIterator: () => makeZipCDHeaderIterator,
|
|
@@ -94,27 +98,41 @@ async function loadZipEntry(jsZip, subFilename, options = {}) {
|
|
|
94
98
|
|
|
95
99
|
// src/zip-writer.ts
|
|
96
100
|
var import_jszip2 = __toESM(require("jszip"), 1);
|
|
101
|
+
var VERSION2 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
|
|
97
102
|
var ZipWriter = {
|
|
98
103
|
name: "Zip Archive",
|
|
104
|
+
id: "zip",
|
|
105
|
+
module: "zip",
|
|
106
|
+
version: VERSION2,
|
|
99
107
|
extensions: ["zip"],
|
|
100
108
|
category: "archive",
|
|
101
109
|
mimeTypes: ["application/zip"],
|
|
102
|
-
|
|
110
|
+
options: {
|
|
111
|
+
zip: {
|
|
112
|
+
onUpdate: () => {
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
jszip: {}
|
|
116
|
+
},
|
|
103
117
|
encode: encodeZipAsync
|
|
104
118
|
};
|
|
105
119
|
async function encodeZipAsync(fileMap, options = {}) {
|
|
120
|
+
var _a;
|
|
106
121
|
const jsZip = new import_jszip2.default();
|
|
107
122
|
for (const subFileName in fileMap) {
|
|
108
123
|
const subFileData = fileMap[subFileName];
|
|
109
124
|
jsZip.file(subFileName, subFileData, (options == null ? void 0 : options.jszip) || {});
|
|
110
125
|
}
|
|
111
|
-
const
|
|
112
|
-
const {
|
|
113
|
-
} } = options;
|
|
126
|
+
const zipOptions = { ...ZipWriter.options.zip, ...options == null ? void 0 : options.zip };
|
|
127
|
+
const jszipOptions = { ...(_a = ZipWriter.options) == null ? void 0 : _a.jszip, ...options.jszip };
|
|
114
128
|
try {
|
|
115
|
-
return await jsZip.generateAsync(
|
|
129
|
+
return await jsZip.generateAsync(
|
|
130
|
+
{ ...jszipOptions, type: "arraybuffer" },
|
|
131
|
+
// generate an arraybuffer
|
|
132
|
+
zipOptions.onUpdate
|
|
133
|
+
);
|
|
116
134
|
} catch (error) {
|
|
117
|
-
options.log.error(`Unable to
|
|
135
|
+
options.log.error(`Unable to encode zip archive: ${error}`);
|
|
118
136
|
throw error;
|
|
119
137
|
}
|
|
120
138
|
}
|
|
@@ -338,7 +356,7 @@ var TarBuilder = class {
|
|
|
338
356
|
var import_loader_utils3 = require("@loaders.gl/loader-utils");
|
|
339
357
|
|
|
340
358
|
// src/parse-zip/end-of-central-directory.ts
|
|
341
|
-
var
|
|
359
|
+
var import_loader_utils2 = require("@loaders.gl/loader-utils");
|
|
342
360
|
|
|
343
361
|
// src/parse-zip/search-from-the-end.ts
|
|
344
362
|
var searchFromTheEnd = async (file, target) => {
|
|
@@ -362,43 +380,8 @@ var searchFromTheEnd = async (file, target) => {
|
|
|
362
380
|
return targetOffset;
|
|
363
381
|
};
|
|
364
382
|
|
|
365
|
-
// src/parse-zip/end-of-central-directory.ts
|
|
366
|
-
var eoCDSignature = new Uint8Array([80, 75, 5, 6]);
|
|
367
|
-
var zip64EoCDLocatorSignature = new Uint8Array([80, 75, 6, 7]);
|
|
368
|
-
var zip64EoCDSignature = new Uint8Array([80, 75, 6, 6]);
|
|
369
|
-
var CD_RECORDS_NUMBER_OFFSET = 8n;
|
|
370
|
-
var CD_START_OFFSET_OFFSET = 16n;
|
|
371
|
-
var ZIP64_EOCD_START_OFFSET_OFFSET = 8n;
|
|
372
|
-
var ZIP64_CD_RECORDS_NUMBER_OFFSET = 24n;
|
|
373
|
-
var ZIP64_CD_START_OFFSET_OFFSET = 48n;
|
|
374
|
-
var parseEoCDRecord = async (file) => {
|
|
375
|
-
const zipEoCDOffset = await searchFromTheEnd(file, eoCDSignature);
|
|
376
|
-
let cdRecordsNumber = BigInt(await file.getUint16(zipEoCDOffset + CD_RECORDS_NUMBER_OFFSET));
|
|
377
|
-
let cdStartOffset = BigInt(await file.getUint32(zipEoCDOffset + CD_START_OFFSET_OFFSET));
|
|
378
|
-
if (cdStartOffset === BigInt(4294967295) || cdRecordsNumber === BigInt(4294967295)) {
|
|
379
|
-
const zip64EoCDLocatorOffset = zipEoCDOffset - 20n;
|
|
380
|
-
const magicBytes = await file.slice(zip64EoCDLocatorOffset, zip64EoCDLocatorOffset + 4n);
|
|
381
|
-
if (!(0, import_loader_utils.compareArrayBuffers)(magicBytes, zip64EoCDLocatorSignature)) {
|
|
382
|
-
throw new Error("zip64 EoCD locator not found");
|
|
383
|
-
}
|
|
384
|
-
const zip64EoCDOffset = await file.getBigUint64(
|
|
385
|
-
zip64EoCDLocatorOffset + ZIP64_EOCD_START_OFFSET_OFFSET
|
|
386
|
-
);
|
|
387
|
-
const endOfCDMagicBytes = await file.slice(zip64EoCDOffset, zip64EoCDOffset + 4n);
|
|
388
|
-
if (!(0, import_loader_utils.compareArrayBuffers)(endOfCDMagicBytes, zip64EoCDSignature.buffer)) {
|
|
389
|
-
throw new Error("zip64 EoCD not found");
|
|
390
|
-
}
|
|
391
|
-
cdRecordsNumber = await file.getBigUint64(zip64EoCDOffset + ZIP64_CD_RECORDS_NUMBER_OFFSET);
|
|
392
|
-
cdStartOffset = await file.getBigUint64(zip64EoCDOffset + ZIP64_CD_START_OFFSET_OFFSET);
|
|
393
|
-
}
|
|
394
|
-
return {
|
|
395
|
-
cdRecordsNumber,
|
|
396
|
-
cdStartOffset
|
|
397
|
-
};
|
|
398
|
-
};
|
|
399
|
-
|
|
400
383
|
// src/parse-zip/zip64-info-generation.ts
|
|
401
|
-
var
|
|
384
|
+
var import_loader_utils = require("@loaders.gl/loader-utils");
|
|
402
385
|
var signature = new Uint8Array([1, 0]);
|
|
403
386
|
function createZip64Info(options) {
|
|
404
387
|
const optionsToUse = {
|
|
@@ -414,14 +397,17 @@ function createZip64Info(options) {
|
|
|
414
397
|
NUMBER_SETTERS[field.size](newValue, 0, optionsToUse[field.name ?? ""] ?? field.default);
|
|
415
398
|
arraysToConcat.push(newValue.buffer);
|
|
416
399
|
}
|
|
417
|
-
return (0,
|
|
400
|
+
return (0, import_loader_utils.concatenateArrayBuffers)(...arraysToConcat);
|
|
401
|
+
}
|
|
402
|
+
function setFieldToNumber(header, fieldSize, fieldOffset, value) {
|
|
403
|
+
NUMBER_SETTERS[fieldSize](header, Number(fieldOffset), value);
|
|
418
404
|
}
|
|
419
405
|
var NUMBER_SETTERS = {
|
|
420
406
|
2: (header, offset, value) => {
|
|
421
|
-
header.setUint16(offset, value, true);
|
|
407
|
+
header.setUint16(offset, Number(value > 65535 ? 65535 : value), true);
|
|
422
408
|
},
|
|
423
409
|
4: (header, offset, value) => {
|
|
424
|
-
header.setUint32(offset, value, true);
|
|
410
|
+
header.setUint32(offset, Number(value > 4294967295 ? 4294967295 : value), true);
|
|
425
411
|
},
|
|
426
412
|
8: (header, offset, value) => {
|
|
427
413
|
header.setBigUint64(offset, BigInt(value), true);
|
|
@@ -455,6 +441,261 @@ var ZIP64_FIELDS = [
|
|
|
455
441
|
}
|
|
456
442
|
];
|
|
457
443
|
|
|
444
|
+
// src/parse-zip/end-of-central-directory.ts
|
|
445
|
+
var eoCDSignature = new Uint8Array([80, 75, 5, 6]);
|
|
446
|
+
var zip64EoCDLocatorSignature = new Uint8Array([80, 75, 6, 7]);
|
|
447
|
+
var zip64EoCDSignature = new Uint8Array([80, 75, 6, 6]);
|
|
448
|
+
var CD_RECORDS_NUMBER_OFFSET = 8n;
|
|
449
|
+
var CD_RECORDS_NUMBER_ON_DISC_OFFSET = 10n;
|
|
450
|
+
var CD_CD_BYTE_SIZE_OFFSET = 12n;
|
|
451
|
+
var CD_START_OFFSET_OFFSET = 16n;
|
|
452
|
+
var CD_COMMENT_OFFSET = 22n;
|
|
453
|
+
var ZIP64_EOCD_START_OFFSET_OFFSET = 8n;
|
|
454
|
+
var ZIP64_CD_RECORDS_NUMBER_OFFSET = 24n;
|
|
455
|
+
var ZIP64_CD_RECORDS_NUMBER_ON_DISC_OFFSET = 32n;
|
|
456
|
+
var ZIP64_CD_CD_BYTE_SIZE_OFFSET = 40n;
|
|
457
|
+
var ZIP64_CD_START_OFFSET_OFFSET = 48n;
|
|
458
|
+
var ZIP64_COMMENT_OFFSET = 56n;
|
|
459
|
+
var parseEoCDRecord = async (file) => {
|
|
460
|
+
const zipEoCDOffset = await searchFromTheEnd(file, eoCDSignature);
|
|
461
|
+
let cdRecordsNumber = BigInt(await file.getUint16(zipEoCDOffset + CD_RECORDS_NUMBER_OFFSET));
|
|
462
|
+
let cdStartOffset = BigInt(await file.getUint32(zipEoCDOffset + CD_START_OFFSET_OFFSET));
|
|
463
|
+
let zip64EoCDLocatorOffset = zipEoCDOffset - 20n;
|
|
464
|
+
let zip64EoCDOffset = 0n;
|
|
465
|
+
const magicBytes = await file.slice(zip64EoCDLocatorOffset, zip64EoCDLocatorOffset + 4n);
|
|
466
|
+
if ((0, import_loader_utils2.compareArrayBuffers)(magicBytes, zip64EoCDLocatorSignature)) {
|
|
467
|
+
zip64EoCDOffset = await file.getBigUint64(
|
|
468
|
+
zip64EoCDLocatorOffset + ZIP64_EOCD_START_OFFSET_OFFSET
|
|
469
|
+
);
|
|
470
|
+
const endOfCDMagicBytes = await file.slice(zip64EoCDOffset, zip64EoCDOffset + 4n);
|
|
471
|
+
if (!(0, import_loader_utils2.compareArrayBuffers)(endOfCDMagicBytes, zip64EoCDSignature.buffer)) {
|
|
472
|
+
throw new Error("zip64 EoCD not found");
|
|
473
|
+
}
|
|
474
|
+
cdRecordsNumber = await file.getBigUint64(zip64EoCDOffset + ZIP64_CD_RECORDS_NUMBER_OFFSET);
|
|
475
|
+
cdStartOffset = await file.getBigUint64(zip64EoCDOffset + ZIP64_CD_START_OFFSET_OFFSET);
|
|
476
|
+
} else {
|
|
477
|
+
zip64EoCDLocatorOffset = 0n;
|
|
478
|
+
}
|
|
479
|
+
return {
|
|
480
|
+
cdRecordsNumber,
|
|
481
|
+
cdStartOffset,
|
|
482
|
+
offsets: {
|
|
483
|
+
zip64EoCDOffset,
|
|
484
|
+
zip64EoCDLocatorOffset,
|
|
485
|
+
zipEoCDOffset
|
|
486
|
+
}
|
|
487
|
+
};
|
|
488
|
+
};
|
|
489
|
+
function updateEoCD(eocdBody, oldEoCDOffsets, newCDStartOffset, eocdStartOffset, newCDRecordsNumber) {
|
|
490
|
+
const eocd = new DataView(eocdBody);
|
|
491
|
+
const classicEoCDOffset = oldEoCDOffsets.zip64EoCDOffset ? oldEoCDOffsets.zipEoCDOffset - oldEoCDOffsets.zip64EoCDOffset : 0n;
|
|
492
|
+
if (Number(newCDRecordsNumber) <= 65535) {
|
|
493
|
+
setFieldToNumber(eocd, 2, classicEoCDOffset + CD_RECORDS_NUMBER_OFFSET, newCDRecordsNumber);
|
|
494
|
+
setFieldToNumber(
|
|
495
|
+
eocd,
|
|
496
|
+
2,
|
|
497
|
+
classicEoCDOffset + CD_RECORDS_NUMBER_ON_DISC_OFFSET,
|
|
498
|
+
newCDRecordsNumber
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
if (eocdStartOffset - newCDStartOffset <= 4294967295) {
|
|
502
|
+
setFieldToNumber(
|
|
503
|
+
eocd,
|
|
504
|
+
4,
|
|
505
|
+
classicEoCDOffset + CD_CD_BYTE_SIZE_OFFSET,
|
|
506
|
+
eocdStartOffset - newCDStartOffset
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
if (newCDStartOffset < 4294967295) {
|
|
510
|
+
setFieldToNumber(eocd, 4, classicEoCDOffset + CD_START_OFFSET_OFFSET, newCDStartOffset);
|
|
511
|
+
}
|
|
512
|
+
if (oldEoCDOffsets.zip64EoCDLocatorOffset && oldEoCDOffsets.zip64EoCDOffset) {
|
|
513
|
+
const locatorOffset = oldEoCDOffsets.zip64EoCDLocatorOffset - oldEoCDOffsets.zip64EoCDOffset;
|
|
514
|
+
setFieldToNumber(eocd, 8, locatorOffset + ZIP64_EOCD_START_OFFSET_OFFSET, eocdStartOffset);
|
|
515
|
+
setFieldToNumber(eocd, 8, ZIP64_CD_START_OFFSET_OFFSET, newCDStartOffset);
|
|
516
|
+
setFieldToNumber(eocd, 8, ZIP64_CD_RECORDS_NUMBER_OFFSET, newCDRecordsNumber);
|
|
517
|
+
setFieldToNumber(eocd, 8, ZIP64_CD_RECORDS_NUMBER_ON_DISC_OFFSET, newCDRecordsNumber);
|
|
518
|
+
setFieldToNumber(eocd, 8, ZIP64_CD_CD_BYTE_SIZE_OFFSET, eocdStartOffset - newCDStartOffset);
|
|
519
|
+
}
|
|
520
|
+
return new Uint8Array(eocd.buffer);
|
|
521
|
+
}
|
|
522
|
+
function generateEoCD(options) {
|
|
523
|
+
const header = new DataView(new ArrayBuffer(Number(CD_COMMENT_OFFSET)));
|
|
524
|
+
for (const field of EOCD_FIELDS) {
|
|
525
|
+
setFieldToNumber(
|
|
526
|
+
header,
|
|
527
|
+
field.size,
|
|
528
|
+
field.offset,
|
|
529
|
+
options[field.name ?? ""] ?? field.default ?? 0
|
|
530
|
+
);
|
|
531
|
+
}
|
|
532
|
+
const locator = generateZip64InfoLocator(options);
|
|
533
|
+
const zip64Record = generateZip64Info(options);
|
|
534
|
+
return (0, import_loader_utils2.concatenateArrayBuffers)(zip64Record, locator, header.buffer);
|
|
535
|
+
}
|
|
536
|
+
var EOCD_FIELDS = [
|
|
537
|
+
// End of central directory signature = 0x06054b50
|
|
538
|
+
{
|
|
539
|
+
offset: 0,
|
|
540
|
+
size: 4,
|
|
541
|
+
default: new DataView(eoCDSignature.buffer).getUint32(0, true)
|
|
542
|
+
},
|
|
543
|
+
// Number of this disk (or 0xffff for ZIP64)
|
|
544
|
+
{
|
|
545
|
+
offset: 4,
|
|
546
|
+
size: 2,
|
|
547
|
+
default: 0
|
|
548
|
+
},
|
|
549
|
+
// Disk where central directory starts (or 0xffff for ZIP64)
|
|
550
|
+
{
|
|
551
|
+
offset: 6,
|
|
552
|
+
size: 2,
|
|
553
|
+
default: 0
|
|
554
|
+
},
|
|
555
|
+
// Number of central directory records on this disk (or 0xffff for ZIP64)
|
|
556
|
+
{
|
|
557
|
+
offset: 8,
|
|
558
|
+
size: 2,
|
|
559
|
+
name: "recordsNumber"
|
|
560
|
+
},
|
|
561
|
+
// Total number of central directory records (or 0xffff for ZIP64)
|
|
562
|
+
{
|
|
563
|
+
offset: 10,
|
|
564
|
+
size: 2,
|
|
565
|
+
name: "recordsNumber"
|
|
566
|
+
},
|
|
567
|
+
// Size of central directory (bytes) (or 0xffffffff for ZIP64)
|
|
568
|
+
{
|
|
569
|
+
offset: 12,
|
|
570
|
+
size: 4,
|
|
571
|
+
name: "cdSize"
|
|
572
|
+
},
|
|
573
|
+
// Offset of start of central directory, relative to start of archive (or 0xffffffff for ZIP64)
|
|
574
|
+
{
|
|
575
|
+
offset: 16,
|
|
576
|
+
size: 4,
|
|
577
|
+
name: "cdOffset"
|
|
578
|
+
},
|
|
579
|
+
// Comment length (n)
|
|
580
|
+
{
|
|
581
|
+
offset: 20,
|
|
582
|
+
size: 2,
|
|
583
|
+
default: 0
|
|
584
|
+
}
|
|
585
|
+
];
|
|
586
|
+
function generateZip64Info(options) {
|
|
587
|
+
const record = new DataView(new ArrayBuffer(Number(ZIP64_COMMENT_OFFSET)));
|
|
588
|
+
for (const field of ZIP64_EOCD_FIELDS) {
|
|
589
|
+
setFieldToNumber(
|
|
590
|
+
record,
|
|
591
|
+
field.size,
|
|
592
|
+
field.offset,
|
|
593
|
+
options[field.name ?? ""] ?? field.default ?? 0
|
|
594
|
+
);
|
|
595
|
+
}
|
|
596
|
+
return record.buffer;
|
|
597
|
+
}
|
|
598
|
+
function generateZip64InfoLocator(options) {
|
|
599
|
+
const locator = new DataView(new ArrayBuffer(Number(20)));
|
|
600
|
+
for (const field of ZIP64_EOCD_LOCATOR_FIELDS) {
|
|
601
|
+
setFieldToNumber(
|
|
602
|
+
locator,
|
|
603
|
+
field.size,
|
|
604
|
+
field.offset,
|
|
605
|
+
options[field.name ?? ""] ?? field.default ?? 0
|
|
606
|
+
);
|
|
607
|
+
}
|
|
608
|
+
return locator.buffer;
|
|
609
|
+
}
|
|
610
|
+
var ZIP64_EOCD_LOCATOR_FIELDS = [
|
|
611
|
+
// zip64 end of central dir locator signature
|
|
612
|
+
{
|
|
613
|
+
offset: 0,
|
|
614
|
+
size: 4,
|
|
615
|
+
default: new DataView(zip64EoCDLocatorSignature.buffer).getUint32(0, true)
|
|
616
|
+
},
|
|
617
|
+
// number of the disk with the start of the zip64 end of
|
|
618
|
+
{
|
|
619
|
+
offset: 4,
|
|
620
|
+
size: 4,
|
|
621
|
+
default: 0
|
|
622
|
+
},
|
|
623
|
+
// start of the zip64 end of central directory
|
|
624
|
+
{
|
|
625
|
+
offset: 8,
|
|
626
|
+
size: 8,
|
|
627
|
+
name: "eoCDStart"
|
|
628
|
+
},
|
|
629
|
+
// total number of disks
|
|
630
|
+
{
|
|
631
|
+
offset: 16,
|
|
632
|
+
size: 4,
|
|
633
|
+
default: 1
|
|
634
|
+
}
|
|
635
|
+
];
|
|
636
|
+
var ZIP64_EOCD_FIELDS = [
|
|
637
|
+
// End of central directory signature = 0x06064b50
|
|
638
|
+
{
|
|
639
|
+
offset: 0,
|
|
640
|
+
size: 4,
|
|
641
|
+
default: new DataView(zip64EoCDSignature.buffer).getUint32(0, true)
|
|
642
|
+
},
|
|
643
|
+
// Size of the EOCD64 minus 12
|
|
644
|
+
{
|
|
645
|
+
offset: 4,
|
|
646
|
+
size: 8,
|
|
647
|
+
default: 44
|
|
648
|
+
},
|
|
649
|
+
// Version made by
|
|
650
|
+
{
|
|
651
|
+
offset: 12,
|
|
652
|
+
size: 2,
|
|
653
|
+
default: 45
|
|
654
|
+
},
|
|
655
|
+
// Version needed to extract (minimum)
|
|
656
|
+
{
|
|
657
|
+
offset: 14,
|
|
658
|
+
size: 2,
|
|
659
|
+
default: 45
|
|
660
|
+
},
|
|
661
|
+
// Number of this disk
|
|
662
|
+
{
|
|
663
|
+
offset: 16,
|
|
664
|
+
size: 4,
|
|
665
|
+
default: 0
|
|
666
|
+
},
|
|
667
|
+
// Disk where central directory starts
|
|
668
|
+
{
|
|
669
|
+
offset: 20,
|
|
670
|
+
size: 4,
|
|
671
|
+
default: 0
|
|
672
|
+
},
|
|
673
|
+
// Number of central directory records on this disk
|
|
674
|
+
{
|
|
675
|
+
offset: 24,
|
|
676
|
+
size: 8,
|
|
677
|
+
name: "recordsNumber"
|
|
678
|
+
},
|
|
679
|
+
// Total number of central directory records
|
|
680
|
+
{
|
|
681
|
+
offset: 32,
|
|
682
|
+
size: 8,
|
|
683
|
+
name: "recordsNumber"
|
|
684
|
+
},
|
|
685
|
+
// Size of central directory (bytes)
|
|
686
|
+
{
|
|
687
|
+
offset: 40,
|
|
688
|
+
size: 8,
|
|
689
|
+
name: "cdSize"
|
|
690
|
+
},
|
|
691
|
+
// Offset of start of central directory, relative to start of archive
|
|
692
|
+
{
|
|
693
|
+
offset: 48,
|
|
694
|
+
size: 8,
|
|
695
|
+
name: "cdOffset"
|
|
696
|
+
}
|
|
697
|
+
];
|
|
698
|
+
|
|
458
699
|
// src/parse-zip/cd-file-header.ts
|
|
459
700
|
var CD_COMPRESSED_SIZE_OFFSET = 20n;
|
|
460
701
|
var CD_UNCOMPRESSED_SIZE_OFFSET = 24n;
|
|
@@ -558,7 +799,7 @@ function generateCDHeader(options) {
|
|
|
558
799
|
const optionsToZip64 = {};
|
|
559
800
|
if (optionsToUse.offset >= 4294967295) {
|
|
560
801
|
optionsToZip64.offset = optionsToUse.offset;
|
|
561
|
-
optionsToUse.offset = 4294967295;
|
|
802
|
+
optionsToUse.offset = BigInt(4294967295);
|
|
562
803
|
}
|
|
563
804
|
if (optionsToUse.length >= 4294967295) {
|
|
564
805
|
optionsToZip64.size = optionsToUse.length;
|
|
@@ -568,10 +809,11 @@ function generateCDHeader(options) {
|
|
|
568
809
|
zip64header = createZip64Info(optionsToZip64);
|
|
569
810
|
optionsToUse.extraLength = zip64header.byteLength;
|
|
570
811
|
}
|
|
571
|
-
const header = new DataView(new ArrayBuffer(
|
|
812
|
+
const header = new DataView(new ArrayBuffer(Number(CD_FILE_NAME_OFFSET)));
|
|
572
813
|
for (const field of ZIP_HEADER_FIELDS) {
|
|
573
|
-
|
|
814
|
+
setFieldToNumber(
|
|
574
815
|
header,
|
|
816
|
+
field.size,
|
|
575
817
|
field.offset,
|
|
576
818
|
optionsToUse[field.name ?? ""] ?? field.default ?? 0
|
|
577
819
|
);
|
|
@@ -734,9 +976,222 @@ var parseZipLocalFileHeader = async (headerOffset, buffer) => {
|
|
|
734
976
|
compressionMethod
|
|
735
977
|
};
|
|
736
978
|
};
|
|
979
|
+
function generateLocalHeader(options) {
|
|
980
|
+
const optionsToUse = {
|
|
981
|
+
...options,
|
|
982
|
+
extraLength: 0,
|
|
983
|
+
fnlength: options.fileName.length
|
|
984
|
+
};
|
|
985
|
+
let zip64header = new ArrayBuffer(0);
|
|
986
|
+
const optionsToZip64 = {};
|
|
987
|
+
if (optionsToUse.length >= 4294967295) {
|
|
988
|
+
optionsToZip64.size = optionsToUse.length;
|
|
989
|
+
optionsToUse.length = 4294967295;
|
|
990
|
+
}
|
|
991
|
+
if (Object.keys(optionsToZip64).length) {
|
|
992
|
+
zip64header = createZip64Info(optionsToZip64);
|
|
993
|
+
optionsToUse.extraLength = zip64header.byteLength;
|
|
994
|
+
}
|
|
995
|
+
const header = new DataView(new ArrayBuffer(Number(FILE_NAME_OFFSET)));
|
|
996
|
+
for (const field of ZIP_HEADER_FIELDS2) {
|
|
997
|
+
setFieldToNumber(
|
|
998
|
+
header,
|
|
999
|
+
field.size,
|
|
1000
|
+
field.offset,
|
|
1001
|
+
optionsToUse[field.name ?? ""] ?? field.default ?? 0
|
|
1002
|
+
);
|
|
1003
|
+
}
|
|
1004
|
+
const encodedName = new TextEncoder().encode(optionsToUse.fileName);
|
|
1005
|
+
const resHeader = (0, import_loader_utils4.concatenateArrayBuffers)(header.buffer, encodedName, zip64header);
|
|
1006
|
+
return resHeader;
|
|
1007
|
+
}
|
|
1008
|
+
var ZIP_HEADER_FIELDS2 = [
|
|
1009
|
+
// Local file header signature = 0x04034b50
|
|
1010
|
+
{
|
|
1011
|
+
offset: 0,
|
|
1012
|
+
size: 4,
|
|
1013
|
+
default: new DataView(signature3.buffer).getUint32(0, true)
|
|
1014
|
+
},
|
|
1015
|
+
// Version needed to extract (minimum)
|
|
1016
|
+
{
|
|
1017
|
+
offset: 4,
|
|
1018
|
+
size: 2,
|
|
1019
|
+
default: 45
|
|
1020
|
+
},
|
|
1021
|
+
// General purpose bit flag
|
|
1022
|
+
{
|
|
1023
|
+
offset: 6,
|
|
1024
|
+
size: 2,
|
|
1025
|
+
default: 0
|
|
1026
|
+
},
|
|
1027
|
+
// Compression method
|
|
1028
|
+
{
|
|
1029
|
+
offset: 8,
|
|
1030
|
+
size: 2,
|
|
1031
|
+
default: 0
|
|
1032
|
+
},
|
|
1033
|
+
// File last modification time
|
|
1034
|
+
{
|
|
1035
|
+
offset: 10,
|
|
1036
|
+
size: 2,
|
|
1037
|
+
default: 0
|
|
1038
|
+
},
|
|
1039
|
+
// File last modification date
|
|
1040
|
+
{
|
|
1041
|
+
offset: 12,
|
|
1042
|
+
size: 2,
|
|
1043
|
+
default: 0
|
|
1044
|
+
},
|
|
1045
|
+
// CRC-32 of uncompressed data
|
|
1046
|
+
{
|
|
1047
|
+
offset: 14,
|
|
1048
|
+
size: 4,
|
|
1049
|
+
name: "crc32"
|
|
1050
|
+
},
|
|
1051
|
+
// Compressed size (or 0xffffffff for ZIP64)
|
|
1052
|
+
{
|
|
1053
|
+
offset: 18,
|
|
1054
|
+
size: 4,
|
|
1055
|
+
name: "length"
|
|
1056
|
+
},
|
|
1057
|
+
// Uncompressed size (or 0xffffffff for ZIP64)
|
|
1058
|
+
{
|
|
1059
|
+
offset: 22,
|
|
1060
|
+
size: 4,
|
|
1061
|
+
name: "length"
|
|
1062
|
+
},
|
|
1063
|
+
// File name length (n)
|
|
1064
|
+
{
|
|
1065
|
+
offset: 26,
|
|
1066
|
+
size: 2,
|
|
1067
|
+
name: "fnlength"
|
|
1068
|
+
},
|
|
1069
|
+
// Extra field length (m)
|
|
1070
|
+
{
|
|
1071
|
+
offset: 28,
|
|
1072
|
+
size: 2,
|
|
1073
|
+
default: 0,
|
|
1074
|
+
name: "extraLength"
|
|
1075
|
+
}
|
|
1076
|
+
];
|
|
737
1077
|
|
|
738
|
-
// src/
|
|
1078
|
+
// src/parse-zip/zip-composition.ts
|
|
1079
|
+
var import_loader_utils5 = require("@loaders.gl/loader-utils");
|
|
739
1080
|
var import_crypto = require("@loaders.gl/crypto");
|
|
1081
|
+
var import_core = require("@loaders.gl/core");
|
|
1082
|
+
async function cutTheTailOff(provider) {
|
|
1083
|
+
const oldEoCDinfo = await parseEoCDRecord(provider);
|
|
1084
|
+
const oldCDStartOffset = oldEoCDinfo.cdStartOffset;
|
|
1085
|
+
const oldCDLength = Number(
|
|
1086
|
+
oldEoCDinfo.offsets.zip64EoCDOffset ? oldEoCDinfo.offsets.zip64EoCDOffset - oldCDStartOffset : oldEoCDinfo.offsets.zipEoCDOffset - oldCDStartOffset
|
|
1087
|
+
);
|
|
1088
|
+
const zipEnding = await provider.slice(oldCDStartOffset, provider.length);
|
|
1089
|
+
await provider.truncate(Number(oldCDStartOffset));
|
|
1090
|
+
const oldCDBody = zipEnding.slice(0, oldCDLength);
|
|
1091
|
+
const eocdBody = zipEnding.slice(oldCDLength, zipEnding.byteLength);
|
|
1092
|
+
return [oldCDBody, eocdBody, oldEoCDinfo];
|
|
1093
|
+
}
|
|
1094
|
+
async function generateFileHeaders(fileName, fileToAdd, localFileHeaderOffset) {
|
|
1095
|
+
const newFileCRC322 = parseInt(await new import_crypto.CRC32Hash().hash(fileToAdd, "hex"), 16);
|
|
1096
|
+
const newFileLocalHeader = generateLocalHeader({
|
|
1097
|
+
crc32: newFileCRC322,
|
|
1098
|
+
fileName,
|
|
1099
|
+
length: fileToAdd.byteLength
|
|
1100
|
+
});
|
|
1101
|
+
const newFileCDHeader = generateCDHeader({
|
|
1102
|
+
crc32: newFileCRC322,
|
|
1103
|
+
fileName,
|
|
1104
|
+
offset: localFileHeaderOffset,
|
|
1105
|
+
length: fileToAdd.byteLength
|
|
1106
|
+
});
|
|
1107
|
+
return [
|
|
1108
|
+
new Uint8Array((0, import_loader_utils5.concatenateArrayBuffers)(newFileLocalHeader, fileToAdd)),
|
|
1109
|
+
new Uint8Array(newFileCDHeader)
|
|
1110
|
+
];
|
|
1111
|
+
}
|
|
1112
|
+
async function addOneFile(zipUrl, fileToAdd, fileName) {
|
|
1113
|
+
const provider = new import_loader_utils5.FileHandleFile(zipUrl, true);
|
|
1114
|
+
const [oldCDBody, eocdBody, oldEoCDinfo] = await cutTheTailOff(provider);
|
|
1115
|
+
const newFileOffset = provider.length;
|
|
1116
|
+
const [localPart, cdHeaderPart] = await generateFileHeaders(fileName, fileToAdd, newFileOffset);
|
|
1117
|
+
await provider.append(localPart);
|
|
1118
|
+
const newCDBody = (0, import_loader_utils5.concatenateArrayBuffers)(oldCDBody, cdHeaderPart);
|
|
1119
|
+
const newCDStartOffset = provider.length;
|
|
1120
|
+
await provider.append(new Uint8Array(newCDBody));
|
|
1121
|
+
const eocdOffset = provider.length;
|
|
1122
|
+
await provider.append(
|
|
1123
|
+
updateEoCD(
|
|
1124
|
+
eocdBody,
|
|
1125
|
+
oldEoCDinfo.offsets,
|
|
1126
|
+
newCDStartOffset,
|
|
1127
|
+
eocdOffset,
|
|
1128
|
+
oldEoCDinfo.cdRecordsNumber + 1n
|
|
1129
|
+
)
|
|
1130
|
+
);
|
|
1131
|
+
}
|
|
1132
|
+
async function createZip(inputPath, outputPath, createAdditionalData) {
|
|
1133
|
+
const fileIterator = getFileIterator(inputPath);
|
|
1134
|
+
const resFile = new import_loader_utils5.NodeFile(outputPath, "w");
|
|
1135
|
+
const fileList = [];
|
|
1136
|
+
const cdArray = [];
|
|
1137
|
+
for await (const file of fileIterator) {
|
|
1138
|
+
await addFile(file, resFile, cdArray, fileList);
|
|
1139
|
+
}
|
|
1140
|
+
if (createAdditionalData) {
|
|
1141
|
+
const additionaldata = await createAdditionalData(fileList);
|
|
1142
|
+
console.log(additionaldata);
|
|
1143
|
+
await addFile(additionaldata, resFile, cdArray);
|
|
1144
|
+
}
|
|
1145
|
+
const cdOffset = (await resFile.stat()).bigsize;
|
|
1146
|
+
const cd = (0, import_loader_utils5.concatenateArrayBuffers)(...cdArray);
|
|
1147
|
+
await resFile.append(new Uint8Array(cd));
|
|
1148
|
+
const eoCDStart = (await resFile.stat()).bigsize;
|
|
1149
|
+
await resFile.append(
|
|
1150
|
+
new Uint8Array(
|
|
1151
|
+
generateEoCD({ recordsNumber: cdArray.length, cdSize: cd.byteLength, cdOffset, eoCDStart })
|
|
1152
|
+
)
|
|
1153
|
+
);
|
|
1154
|
+
}
|
|
1155
|
+
async function addFile(file, resFile, cdArray, fileList) {
|
|
1156
|
+
const size = (await resFile.stat()).bigsize;
|
|
1157
|
+
fileList == null ? void 0 : fileList.push({ fileName: file.path, localHeaderOffset: size });
|
|
1158
|
+
const [localPart, cdHeaderPart] = await generateFileHeaders(file.path, file.file, size);
|
|
1159
|
+
await resFile.append(localPart);
|
|
1160
|
+
cdArray.push(cdHeaderPart);
|
|
1161
|
+
}
|
|
1162
|
+
function getFileIterator(inputPath) {
|
|
1163
|
+
async function* iterable() {
|
|
1164
|
+
const fileList = await getAllFiles(inputPath);
|
|
1165
|
+
for (const filePath of fileList) {
|
|
1166
|
+
const file = await (await (0, import_core.fetchFile)(import_loader_utils5.path.join(inputPath, filePath))).arrayBuffer();
|
|
1167
|
+
yield { path: filePath, file };
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
return iterable();
|
|
1171
|
+
}
|
|
1172
|
+
async function getAllFiles(basePath, subfolder = "", fsPassed) {
|
|
1173
|
+
const fs = fsPassed ? fsPassed : new import_loader_utils5.NodeFilesystem({});
|
|
1174
|
+
const files = await fs.readdir(pathJoin(basePath, subfolder));
|
|
1175
|
+
const arrayOfFiles = [];
|
|
1176
|
+
for (const file of files) {
|
|
1177
|
+
const fullPath = pathJoin(basePath, subfolder, file);
|
|
1178
|
+
if ((await fs.stat(fullPath)).isDirectory) {
|
|
1179
|
+
const files2 = await getAllFiles(basePath, pathJoin(subfolder, file));
|
|
1180
|
+
arrayOfFiles.push(...files2);
|
|
1181
|
+
} else {
|
|
1182
|
+
arrayOfFiles.push(pathJoin(subfolder, file));
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
return arrayOfFiles;
|
|
1186
|
+
}
|
|
1187
|
+
function pathJoin(...paths) {
|
|
1188
|
+
const resPaths = paths.filter((val) => val.length);
|
|
1189
|
+
return import_loader_utils5.path.join(...resPaths);
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
// src/hash-file-utility.ts
|
|
1193
|
+
var import_crypto2 = require("@loaders.gl/crypto");
|
|
1194
|
+
var import_loader_utils6 = require("@loaders.gl/loader-utils");
|
|
740
1195
|
function parseHashTable(arrayBuffer) {
|
|
741
1196
|
const dataView = new DataView(arrayBuffer);
|
|
742
1197
|
const hashMap = {};
|
|
@@ -752,7 +1207,10 @@ function bufferToHex(buffer, start, length) {
|
|
|
752
1207
|
}
|
|
753
1208
|
async function makeHashTableFromZipHeaders(fileProvider) {
|
|
754
1209
|
const zipCDIterator = makeZipCDHeaderIterator(fileProvider);
|
|
755
|
-
|
|
1210
|
+
return getHashTable(zipCDIterator);
|
|
1211
|
+
}
|
|
1212
|
+
async function getHashTable(zipCDIterator) {
|
|
1213
|
+
const md5Hash = new import_crypto2.MD5Hash();
|
|
756
1214
|
const textEncoder = new TextEncoder();
|
|
757
1215
|
const hashTable = {};
|
|
758
1216
|
for await (const cdHeader of zipCDIterator) {
|
|
@@ -763,11 +1221,39 @@ async function makeHashTableFromZipHeaders(fileProvider) {
|
|
|
763
1221
|
}
|
|
764
1222
|
return hashTable;
|
|
765
1223
|
}
|
|
1224
|
+
async function composeHashFile(zipCDIterator) {
|
|
1225
|
+
const md5Hash = new import_crypto2.MD5Hash();
|
|
1226
|
+
const textEncoder = new TextEncoder();
|
|
1227
|
+
const hashArray = [];
|
|
1228
|
+
for await (const cdHeader of zipCDIterator) {
|
|
1229
|
+
const filename = cdHeader.fileName.split("\\").join("/").toLocaleLowerCase();
|
|
1230
|
+
const arrayBuffer = textEncoder.encode(filename).buffer;
|
|
1231
|
+
const md5 = await md5Hash.hash(arrayBuffer, "hex");
|
|
1232
|
+
hashArray.push(
|
|
1233
|
+
(0, import_loader_utils6.concatenateArrayBuffers)(hexStringToBuffer(md5), bigintToBuffer(cdHeader.localHeaderOffset))
|
|
1234
|
+
);
|
|
1235
|
+
}
|
|
1236
|
+
const bufferArray = hashArray.sort(compareHashes);
|
|
1237
|
+
return (0, import_loader_utils6.concatenateArrayBuffersFromArray)(bufferArray);
|
|
1238
|
+
}
|
|
1239
|
+
function compareHashes(arrA, arrB) {
|
|
1240
|
+
const a = new BigUint64Array(arrA);
|
|
1241
|
+
const b = new BigUint64Array(arrB);
|
|
1242
|
+
return Number(a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]);
|
|
1243
|
+
}
|
|
1244
|
+
function hexStringToBuffer(str) {
|
|
1245
|
+
var _a;
|
|
1246
|
+
const byteArray = (_a = str.match(/../g)) == null ? void 0 : _a.map((h) => parseInt(h, 16));
|
|
1247
|
+
return new Uint8Array(byteArray ?? new Array(16)).buffer;
|
|
1248
|
+
}
|
|
1249
|
+
function bigintToBuffer(n) {
|
|
1250
|
+
return new BigUint64Array([n]).buffer;
|
|
1251
|
+
}
|
|
766
1252
|
|
|
767
1253
|
// src/filesystems/zip-filesystem.ts
|
|
768
|
-
var import_loader_utils5 = require("@loaders.gl/loader-utils");
|
|
769
|
-
var import_loader_utils6 = require("@loaders.gl/loader-utils");
|
|
770
1254
|
var import_loader_utils7 = require("@loaders.gl/loader-utils");
|
|
1255
|
+
var import_loader_utils8 = require("@loaders.gl/loader-utils");
|
|
1256
|
+
var import_loader_utils9 = require("@loaders.gl/loader-utils");
|
|
771
1257
|
var import_compression = require("@loaders.gl/compression");
|
|
772
1258
|
var COMPRESSION_METHODS = {
|
|
773
1259
|
/** No compression */
|
|
@@ -789,12 +1275,12 @@ var ZipFileSystem = class {
|
|
|
789
1275
|
this.fileProvider = null;
|
|
790
1276
|
if (typeof file === "string") {
|
|
791
1277
|
this.fileName = file;
|
|
792
|
-
if (!
|
|
793
|
-
this.fileProvider = new
|
|
1278
|
+
if (!import_loader_utils7.isBrowser) {
|
|
1279
|
+
this.fileProvider = new import_loader_utils9.FileHandleFile(file);
|
|
794
1280
|
} else {
|
|
795
1281
|
throw new Error("Cannot open file for random access in a WEB browser");
|
|
796
1282
|
}
|
|
797
|
-
} else if ((0,
|
|
1283
|
+
} else if ((0, import_loader_utils8.isFileProvider)(file)) {
|
|
798
1284
|
this.fileProvider = file;
|
|
799
1285
|
}
|
|
800
1286
|
}
|