@loaders.gl/zip 4.0.4 → 4.1.0-alpha.10

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.
Files changed (68) hide show
  1. package/dist/dist.dev.js +434 -27
  2. package/dist/filesystems/zip-filesystem.d.ts.map +1 -1
  3. package/dist/filesystems/zip-filesystem.js.map +1 -1
  4. package/dist/hash-file-utility.d.ts +6 -0
  5. package/dist/hash-file-utility.d.ts.map +1 -1
  6. package/dist/hash-file-utility.js +22 -0
  7. package/dist/hash-file-utility.js.map +1 -1
  8. package/dist/index.cjs +462 -32
  9. package/dist/index.d.ts +4 -3
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +4 -3
  12. package/dist/index.js.map +1 -1
  13. package/dist/lib/tar/header.d.ts.map +1 -1
  14. package/dist/lib/tar/header.js.map +1 -1
  15. package/dist/lib/tar/tar.d.ts.map +1 -1
  16. package/dist/lib/tar/tar.js.map +1 -1
  17. package/dist/lib/tar/types.d.ts.map +1 -1
  18. package/dist/lib/tar/types.js.map +1 -1
  19. package/dist/lib/tar/utils.d.ts.map +1 -1
  20. package/dist/lib/tar/utils.js.map +1 -1
  21. package/dist/parse-zip/cd-file-header.d.ts +18 -0
  22. package/dist/parse-zip/cd-file-header.d.ts.map +1 -1
  23. package/dist/parse-zip/cd-file-header.js +101 -1
  24. package/dist/parse-zip/cd-file-header.js.map +1 -1
  25. package/dist/parse-zip/end-of-central-directory.d.ts +19 -0
  26. package/dist/parse-zip/end-of-central-directory.d.ts.map +1 -1
  27. package/dist/parse-zip/end-of-central-directory.js +41 -8
  28. package/dist/parse-zip/end-of-central-directory.js.map +1 -1
  29. package/dist/parse-zip/local-file-header.d.ts +16 -0
  30. package/dist/parse-zip/local-file-header.d.ts.map +1 -1
  31. package/dist/parse-zip/local-file-header.js +73 -1
  32. package/dist/parse-zip/local-file-header.js.map +1 -1
  33. package/dist/parse-zip/search-from-the-end.d.ts.map +1 -1
  34. package/dist/parse-zip/search-from-the-end.js.map +1 -1
  35. package/dist/parse-zip/zip-compozition.d.ts +8 -0
  36. package/dist/parse-zip/zip-compozition.d.ts.map +1 -0
  37. package/dist/parse-zip/zip-compozition.js +43 -0
  38. package/dist/parse-zip/zip-compozition.js.map +1 -0
  39. package/dist/parse-zip/zip64-info-generation.d.ts +24 -0
  40. package/dist/parse-zip/zip64-info-generation.d.ts.map +1 -0
  41. package/dist/parse-zip/zip64-info-generation.js +50 -0
  42. package/dist/parse-zip/zip64-info-generation.js.map +1 -0
  43. package/dist/tar-builder.d.ts.map +1 -1
  44. package/dist/tar-builder.js.map +1 -1
  45. package/dist/zip-loader.d.ts.map +1 -1
  46. package/dist/zip-loader.js +1 -1
  47. package/dist/zip-loader.js.map +1 -1
  48. package/dist/zip-writer.d.ts +2 -2
  49. package/dist/zip-writer.d.ts.map +1 -1
  50. package/dist/zip-writer.js +22 -7
  51. package/dist/zip-writer.js.map +1 -1
  52. package/package.json +7 -7
  53. package/src/filesystems/zip-filesystem.ts +2 -1
  54. package/src/hash-file-utility.ts +52 -2
  55. package/src/index.ts +8 -4
  56. package/src/lib/tar/header.ts +2 -1
  57. package/src/lib/tar/tar.ts +2 -1
  58. package/src/lib/tar/types.ts +2 -1
  59. package/src/lib/tar/utils.ts +2 -1
  60. package/src/parse-zip/cd-file-header.ts +185 -2
  61. package/src/parse-zip/end-of-central-directory.ts +99 -9
  62. package/src/parse-zip/local-file-header.ts +128 -2
  63. package/src/parse-zip/search-from-the-end.ts +2 -1
  64. package/src/parse-zip/zip-compozition.ts +113 -0
  65. package/src/parse-zip/zip64-info-generation.ts +106 -0
  66. package/src/tar-builder.ts +2 -1
  67. package/src/zip-loader.ts +2 -1
  68. package/src/zip-writer.ts +24 -10
@@ -1 +1 @@
1
- {"version":3,"file":"hash-file-utility.d.ts","sourceRoot":"","sources":["../src/hash-file-utility.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,YAAY,EAAC,MAAM,0BAA0B,CAAC;AAGtD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAY/E;AASD;;;;GAIG;AACH,wBAAsB,2BAA2B,CAC/C,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAejC"}
1
+ {"version":3,"file":"hash-file-utility.d.ts","sourceRoot":"","sources":["../src/hash-file-utility.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,YAAY,EAGb,MAAM,0BAA0B,CAAC;AAGlC;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAY/E;AASD;;;;GAIG;AACH,wBAAsB,2BAA2B,CAC/C,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAejC;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAMtF"}
@@ -1,4 +1,5 @@
1
1
  import { MD5Hash } from '@loaders.gl/crypto';
2
+ import { concatenateArrayBuffers, concatenateArrayBuffersFromArray } from '@loaders.gl/loader-utils';
2
3
  import { makeZipCDHeaderIterator } from "./parse-zip/cd-file-header.js";
3
4
  export function parseHashTable(arrayBuffer) {
4
5
  const dataView = new DataView(arrayBuffer);
@@ -26,4 +27,25 @@ export async function makeHashTableFromZipHeaders(fileProvider) {
26
27
  }
27
28
  return hashTable;
28
29
  }
30
+ export async function composeHashFile(fileProvider) {
31
+ const hashArray = await makeHashTableFromZipHeaders(fileProvider);
32
+ const bufferArray = Object.entries(hashArray).map(_ref => {
33
+ let [key, value] = _ref;
34
+ return concatenateArrayBuffers(hexStringToBuffer(key), bigintToBuffer(value));
35
+ }).sort(compareHashes);
36
+ return concatenateArrayBuffersFromArray(bufferArray);
37
+ }
38
+ function compareHashes(arrA, arrB) {
39
+ const a = new BigUint64Array(arrA);
40
+ const b = new BigUint64Array(arrB);
41
+ return Number(a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]);
42
+ }
43
+ function hexStringToBuffer(str) {
44
+ var _str$match;
45
+ const byteArray = (_str$match = str.match(/../g)) === null || _str$match === void 0 ? void 0 : _str$match.map(h => parseInt(h, 16));
46
+ return new Uint8Array(byteArray !== null && byteArray !== void 0 ? byteArray : new Array(16)).buffer;
47
+ }
48
+ function bigintToBuffer(n) {
49
+ return new BigUint64Array([n]).buffer;
50
+ }
29
51
  //# sourceMappingURL=hash-file-utility.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hash-file-utility.js","names":["MD5Hash","makeZipCDHeaderIterator","parseHashTable","arrayBuffer","dataView","DataView","hashMap","i","byteLength","offset","getBigUint64","hash","bufferToHex","buffer","start","length","Uint8Array","map","x","toString","padStart","join","makeHashTableFromZipHeaders","fileProvider","zipCDIterator","md5Hash","textEncoder","TextEncoder","hashTable","cdHeader","filename","fileName","split","toLocaleLowerCase","encode","md5","localHeaderOffset"],"sources":["../src/hash-file-utility.ts"],"sourcesContent":["// loaders.gl, MIT license\n// Copyright (c) vis.gl contributors\n\nimport {MD5Hash} from '@loaders.gl/crypto';\nimport {FileProvider} from '@loaders.gl/loader-utils';\nimport {makeZipCDHeaderIterator} from './parse-zip/cd-file-header';\n\n/**\n * Reads hash file from buffer and returns it in ready-to-use form\n * @param arrayBuffer - buffer containing hash file\n * @returns Map containing hash and offset\n */\nexport function parseHashTable(arrayBuffer: ArrayBuffer): Record<string, bigint> {\n const dataView = new DataView(arrayBuffer);\n\n const hashMap: Record<string, bigint> = {};\n\n for (let i = 0; i < arrayBuffer.byteLength; i = i + 24) {\n const offset = dataView.getBigUint64(i + 16, true);\n const hash = bufferToHex(arrayBuffer, i, 16);\n hashMap[hash] = offset;\n }\n\n return hashMap;\n}\n\nfunction bufferToHex(buffer: ArrayBuffer, start: number, length: number): string {\n // buffer is an ArrayBuffer\n return [...new Uint8Array(buffer, start, length)]\n .map((x) => x.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * generates hash info from zip files \"central directory\"\n * @param fileProvider - provider of the archive\n * @returns ready to use hash info\n */\nexport async function makeHashTableFromZipHeaders(\n fileProvider: FileProvider\n): Promise<Record<string, bigint>> {\n const zipCDIterator = makeZipCDHeaderIterator(fileProvider);\n const md5Hash = new MD5Hash();\n const textEncoder = new TextEncoder();\n\n const hashTable: Record<string, bigint> = {};\n\n for await (const cdHeader of zipCDIterator) {\n const filename = cdHeader.fileName.split('\\\\').join('/').toLocaleLowerCase();\n const arrayBuffer = textEncoder.encode(filename).buffer;\n const md5 = await md5Hash.hash(arrayBuffer, 'hex');\n hashTable[md5] = cdHeader.localHeaderOffset;\n }\n\n return hashTable;\n}\n"],"mappings":"AAGA,SAAQA,OAAO,QAAO,oBAAoB;AAAC,SAEnCC,uBAAuB;AAO/B,OAAO,SAASC,cAAcA,CAACC,WAAwB,EAA0B;EAC/E,MAAMC,QAAQ,GAAG,IAAIC,QAAQ,CAACF,WAAW,CAAC;EAE1C,MAAMG,OAA+B,GAAG,CAAC,CAAC;EAE1C,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGJ,WAAW,CAACK,UAAU,EAAED,CAAC,GAAGA,CAAC,GAAG,EAAE,EAAE;IACtD,MAAME,MAAM,GAAGL,QAAQ,CAACM,YAAY,CAACH,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC;IAClD,MAAMI,IAAI,GAAGC,WAAW,CAACT,WAAW,EAAEI,CAAC,EAAE,EAAE,CAAC;IAC5CD,OAAO,CAACK,IAAI,CAAC,GAAGF,MAAM;EACxB;EAEA,OAAOH,OAAO;AAChB;AAEA,SAASM,WAAWA,CAACC,MAAmB,EAAEC,KAAa,EAAEC,MAAc,EAAU;EAE/E,OAAO,CAAC,GAAG,IAAIC,UAAU,CAACH,MAAM,EAAEC,KAAK,EAAEC,MAAM,CAAC,CAAC,CAC9CE,GAAG,CAAEC,CAAC,IAAKA,CAAC,CAACC,QAAQ,CAAC,EAAE,CAAC,CAACC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAC3CC,IAAI,CAAC,EAAE,CAAC;AACb;AAOA,OAAO,eAAeC,2BAA2BA,CAC/CC,YAA0B,EACO;EACjC,MAAMC,aAAa,GAAGvB,uBAAuB,CAACsB,YAAY,CAAC;EAC3D,MAAME,OAAO,GAAG,IAAIzB,OAAO,CAAC,CAAC;EAC7B,MAAM0B,WAAW,GAAG,IAAIC,WAAW,CAAC,CAAC;EAErC,MAAMC,SAAiC,GAAG,CAAC,CAAC;EAE5C,WAAW,MAAMC,QAAQ,IAAIL,aAAa,EAAE;IAC1C,MAAMM,QAAQ,GAAGD,QAAQ,CAACE,QAAQ,CAACC,KAAK,CAAC,IAAI,CAAC,CAACX,IAAI,CAAC,GAAG,CAAC,CAACY,iBAAiB,CAAC,CAAC;IAC5E,MAAM9B,WAAW,GAAGuB,WAAW,CAACQ,MAAM,CAACJ,QAAQ,CAAC,CAACjB,MAAM;IACvD,MAAMsB,GAAG,GAAG,MAAMV,OAAO,CAACd,IAAI,CAACR,WAAW,EAAE,KAAK,CAAC;IAClDyB,SAAS,CAACO,GAAG,CAAC,GAAGN,QAAQ,CAACO,iBAAiB;EAC7C;EAEA,OAAOR,SAAS;AAClB"}
1
+ {"version":3,"file":"hash-file-utility.js","names":["MD5Hash","concatenateArrayBuffers","concatenateArrayBuffersFromArray","makeZipCDHeaderIterator","parseHashTable","arrayBuffer","dataView","DataView","hashMap","i","byteLength","offset","getBigUint64","hash","bufferToHex","buffer","start","length","Uint8Array","map","x","toString","padStart","join","makeHashTableFromZipHeaders","fileProvider","zipCDIterator","md5Hash","textEncoder","TextEncoder","hashTable","cdHeader","filename","fileName","split","toLocaleLowerCase","encode","md5","localHeaderOffset","composeHashFile","hashArray","bufferArray","Object","entries","_ref","key","value","hexStringToBuffer","bigintToBuffer","sort","compareHashes","arrA","arrB","a","BigUint64Array","b","Number","str","_str$match","byteArray","match","h","parseInt","Array","n"],"sources":["../src/hash-file-utility.ts"],"sourcesContent":["// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {MD5Hash} from '@loaders.gl/crypto';\nimport {\n FileProvider,\n concatenateArrayBuffers,\n concatenateArrayBuffersFromArray\n} from '@loaders.gl/loader-utils';\nimport {makeZipCDHeaderIterator} from './parse-zip/cd-file-header';\n\n/**\n * Reads hash file from buffer and returns it in ready-to-use form\n * @param arrayBuffer - buffer containing hash file\n * @returns Map containing hash and offset\n */\nexport function parseHashTable(arrayBuffer: ArrayBuffer): Record<string, bigint> {\n const dataView = new DataView(arrayBuffer);\n\n const hashMap: Record<string, bigint> = {};\n\n for (let i = 0; i < arrayBuffer.byteLength; i = i + 24) {\n const offset = dataView.getBigUint64(i + 16, true);\n const hash = bufferToHex(arrayBuffer, i, 16);\n hashMap[hash] = offset;\n }\n\n return hashMap;\n}\n\nfunction bufferToHex(buffer: ArrayBuffer, start: number, length: number): string {\n // buffer is an ArrayBuffer\n return [...new Uint8Array(buffer, start, length)]\n .map((x) => x.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * generates hash info from zip files \"central directory\"\n * @param fileProvider - provider of the archive\n * @returns ready to use hash info\n */\nexport async function makeHashTableFromZipHeaders(\n fileProvider: FileProvider\n): Promise<Record<string, bigint>> {\n const zipCDIterator = makeZipCDHeaderIterator(fileProvider);\n const md5Hash = new MD5Hash();\n const textEncoder = new TextEncoder();\n\n const hashTable: Record<string, bigint> = {};\n\n for await (const cdHeader of zipCDIterator) {\n const filename = cdHeader.fileName.split('\\\\').join('/').toLocaleLowerCase();\n const arrayBuffer = textEncoder.encode(filename).buffer;\n const md5 = await md5Hash.hash(arrayBuffer, 'hex');\n hashTable[md5] = cdHeader.localHeaderOffset;\n }\n\n return hashTable;\n}\n\n/**\n * creates hash file that later can be added to the SLPK archive\n * @param fileProvider SLPK archive where we need to add hash file\n * @returns ArrayBuffer containing hash file\n */\nexport async function composeHashFile(fileProvider: FileProvider): Promise<ArrayBuffer> {\n const hashArray = await makeHashTableFromZipHeaders(fileProvider);\n const bufferArray = Object.entries(hashArray)\n .map(([key, value]) => concatenateArrayBuffers(hexStringToBuffer(key), bigintToBuffer(value)))\n .sort(compareHashes);\n return concatenateArrayBuffersFromArray(bufferArray);\n}\n\n/**\n * Function to compare md5 hashes according to https://github.com/Esri/i3s-spec/blob/master/docs/2.0/slpk_hashtable.pcsl.md\n * @param arrA first hash to compare\n * @param arrB second hash to compare\n * @returns 0 if equal, negative number if a<b, pozitive if a>b\n */\nfunction compareHashes(arrA: ArrayBuffer, arrB: ArrayBuffer): number {\n const a = new BigUint64Array(arrA);\n const b = new BigUint64Array(arrB);\n\n return Number(a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]);\n}\n\n/**\n * converts hex string to buffer\n * @param str hex string to convert\n * @returns conversion result\n */\nfunction hexStringToBuffer(str: string): ArrayBuffer {\n const byteArray = str.match(/../g)?.map((h) => parseInt(h, 16));\n return new Uint8Array(byteArray ?? new Array(16)).buffer;\n}\n\n/**\n * converts bigint to buffer\n * @param n bigint to convert\n * @returns convertion result\n */\nfunction bigintToBuffer(n: bigint): ArrayBuffer {\n return new BigUint64Array([n]).buffer;\n}\n"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -30,12 +30,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
+ CD_HEADER_SIGNATURE: () => signature2,
33
34
  TarBuilder: () => TarBuilder,
34
35
  ZipFileSystem: () => ZipFileSystem,
35
36
  ZipLoader: () => ZipLoader,
36
37
  ZipWriter: () => ZipWriter,
37
- cdSignature: () => signature,
38
- localHeaderSignature: () => signature2,
38
+ addOneFile: () => addOneFile,
39
+ composeHashFile: () => composeHashFile,
40
+ generateCDHeader: () => generateCDHeader,
41
+ generateLocalHeader: () => generateLocalHeader,
42
+ localHeaderSignature: () => signature3,
39
43
  makeHashTableFromZipHeaders: () => makeHashTableFromZipHeaders,
40
44
  makeZipCDHeaderIterator: () => makeZipCDHeaderIterator,
41
45
  parseEoCDRecord: () => parseEoCDRecord,
@@ -93,27 +97,41 @@ async function loadZipEntry(jsZip, subFilename, options = {}) {
93
97
 
94
98
  // src/zip-writer.ts
95
99
  var import_jszip2 = __toESM(require("jszip"), 1);
100
+ var VERSION2 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
96
101
  var ZipWriter = {
97
102
  name: "Zip Archive",
103
+ id: "zip",
104
+ module: "zip",
105
+ version: VERSION2,
98
106
  extensions: ["zip"],
99
107
  category: "archive",
100
108
  mimeTypes: ["application/zip"],
101
- // @ts-ignore
109
+ options: {
110
+ zip: {
111
+ onUpdate: () => {
112
+ }
113
+ },
114
+ jszip: {}
115
+ },
102
116
  encode: encodeZipAsync
103
117
  };
104
118
  async function encodeZipAsync(fileMap, options = {}) {
119
+ var _a;
105
120
  const jsZip = new import_jszip2.default();
106
121
  for (const subFileName in fileMap) {
107
122
  const subFileData = fileMap[subFileName];
108
123
  jsZip.file(subFileName, subFileData, (options == null ? void 0 : options.jszip) || {});
109
124
  }
110
- const jszipOptions = { ...options == null ? void 0 : options.jszip, type: "arraybuffer" };
111
- const { onUpdate = () => {
112
- } } = options;
125
+ const zipOptions = { ...ZipWriter.options.zip, ...options == null ? void 0 : options.zip };
126
+ const jszipOptions = { ...(_a = ZipWriter.options) == null ? void 0 : _a.jszip, ...options.jszip };
113
127
  try {
114
- return await jsZip.generateAsync(jszipOptions, onUpdate);
128
+ return await jsZip.generateAsync(
129
+ { ...jszipOptions, type: "arraybuffer" },
130
+ // generate an arraybuffer
131
+ zipOptions.onUpdate
132
+ );
115
133
  } catch (error) {
116
- options.log.error(`Unable to write zip archive: ${error}`);
134
+ options.log.error(`Unable to encode zip archive: ${error}`);
117
135
  throw error;
118
136
  }
119
137
  }
@@ -334,10 +352,10 @@ var TarBuilder = class {
334
352
  };
335
353
 
336
354
  // src/parse-zip/cd-file-header.ts
337
- var import_loader_utils2 = require("@loaders.gl/loader-utils");
355
+ var import_loader_utils3 = require("@loaders.gl/loader-utils");
338
356
 
339
357
  // src/parse-zip/end-of-central-directory.ts
340
- var import_loader_utils = require("@loaders.gl/loader-utils");
358
+ var import_loader_utils2 = require("@loaders.gl/loader-utils");
341
359
 
342
360
  // src/parse-zip/search-from-the-end.ts
343
361
  var searchFromTheEnd = async (file, target) => {
@@ -361,40 +379,143 @@ var searchFromTheEnd = async (file, target) => {
361
379
  return targetOffset;
362
380
  };
363
381
 
382
+ // src/parse-zip/zip64-info-generation.ts
383
+ var import_loader_utils = require("@loaders.gl/loader-utils");
384
+ var signature = new Uint8Array([1, 0]);
385
+ function createZip64Info(options) {
386
+ const optionsToUse = {
387
+ ...options,
388
+ zip64Length: (options.offset ? 1 : 0) * 8 + (options.size ? 1 : 0) * 16
389
+ };
390
+ const arraysToConcat = [];
391
+ for (const field of ZIP64_FIELDS) {
392
+ if (!optionsToUse[field.name ?? ""] && !field.default) {
393
+ continue;
394
+ }
395
+ const newValue = new DataView(new ArrayBuffer(field.size));
396
+ NUMBER_SETTERS[field.size](newValue, 0, optionsToUse[field.name ?? ""] ?? field.default);
397
+ arraysToConcat.push(newValue.buffer);
398
+ }
399
+ return (0, import_loader_utils.concatenateArrayBuffers)(...arraysToConcat);
400
+ }
401
+ function setFieldToNumber(header, fieldSize, fieldOffset, value) {
402
+ NUMBER_SETTERS[fieldSize](header, Number(fieldOffset), value);
403
+ }
404
+ var NUMBER_SETTERS = {
405
+ 2: (header, offset, value) => {
406
+ header.setUint16(offset, Number(value), true);
407
+ },
408
+ 4: (header, offset, value) => {
409
+ header.setUint32(offset, Number(value), true);
410
+ },
411
+ 8: (header, offset, value) => {
412
+ header.setBigUint64(offset, BigInt(value), true);
413
+ }
414
+ };
415
+ var ZIP64_FIELDS = [
416
+ // Header ID 0x0001
417
+ {
418
+ size: 2,
419
+ default: new DataView(signature.buffer).getUint16(0, true)
420
+ },
421
+ // Size of the extra field chunk (8, 16, 24 or 28)
422
+ {
423
+ size: 2,
424
+ name: "zip64Length"
425
+ },
426
+ // Original uncompressed file size
427
+ {
428
+ size: 8,
429
+ name: "size"
430
+ },
431
+ // Size of compressed data
432
+ {
433
+ size: 8,
434
+ name: "size"
435
+ },
436
+ // Offset of local header record
437
+ {
438
+ size: 8,
439
+ name: "offset"
440
+ }
441
+ ];
442
+
364
443
  // src/parse-zip/end-of-central-directory.ts
365
444
  var eoCDSignature = new Uint8Array([80, 75, 5, 6]);
366
445
  var zip64EoCDLocatorSignature = new Uint8Array([80, 75, 6, 7]);
367
446
  var zip64EoCDSignature = new Uint8Array([80, 75, 6, 6]);
368
447
  var CD_RECORDS_NUMBER_OFFSET = 8n;
448
+ var CD_RECORDS_NUMBER_ON_DISC_OFFSET = 10n;
449
+ var CD_CD_BYTE_SIZE_OFFSET = 12n;
369
450
  var CD_START_OFFSET_OFFSET = 16n;
370
451
  var ZIP64_EOCD_START_OFFSET_OFFSET = 8n;
371
452
  var ZIP64_CD_RECORDS_NUMBER_OFFSET = 24n;
453
+ var ZIP64_CD_RECORDS_NUMBER_ON_DISC_OFFSET = 32n;
454
+ var ZIP64_CD_CD_BYTE_SIZE_OFFSET = 40n;
372
455
  var ZIP64_CD_START_OFFSET_OFFSET = 48n;
373
456
  var parseEoCDRecord = async (file) => {
374
457
  const zipEoCDOffset = await searchFromTheEnd(file, eoCDSignature);
375
458
  let cdRecordsNumber = BigInt(await file.getUint16(zipEoCDOffset + CD_RECORDS_NUMBER_OFFSET));
376
459
  let cdStartOffset = BigInt(await file.getUint32(zipEoCDOffset + CD_START_OFFSET_OFFSET));
377
- if (cdStartOffset === BigInt(4294967295) || cdRecordsNumber === BigInt(4294967295)) {
378
- const zip64EoCDLocatorOffset = zipEoCDOffset - 20n;
379
- const magicBytes = await file.slice(zip64EoCDLocatorOffset, zip64EoCDLocatorOffset + 4n);
380
- if (!(0, import_loader_utils.compareArrayBuffers)(magicBytes, zip64EoCDLocatorSignature)) {
381
- throw new Error("zip64 EoCD locator not found");
382
- }
383
- const zip64EoCDOffset = await file.getBigUint64(
460
+ let zip64EoCDLocatorOffset = zipEoCDOffset - 20n;
461
+ let zip64EoCDOffset = 0n;
462
+ const magicBytes = await file.slice(zip64EoCDLocatorOffset, zip64EoCDLocatorOffset + 4n);
463
+ if ((0, import_loader_utils2.compareArrayBuffers)(magicBytes, zip64EoCDLocatorSignature)) {
464
+ zip64EoCDOffset = await file.getBigUint64(
384
465
  zip64EoCDLocatorOffset + ZIP64_EOCD_START_OFFSET_OFFSET
385
466
  );
386
467
  const endOfCDMagicBytes = await file.slice(zip64EoCDOffset, zip64EoCDOffset + 4n);
387
- if (!(0, import_loader_utils.compareArrayBuffers)(endOfCDMagicBytes, zip64EoCDSignature.buffer)) {
468
+ if (!(0, import_loader_utils2.compareArrayBuffers)(endOfCDMagicBytes, zip64EoCDSignature.buffer)) {
388
469
  throw new Error("zip64 EoCD not found");
389
470
  }
390
471
  cdRecordsNumber = await file.getBigUint64(zip64EoCDOffset + ZIP64_CD_RECORDS_NUMBER_OFFSET);
391
472
  cdStartOffset = await file.getBigUint64(zip64EoCDOffset + ZIP64_CD_START_OFFSET_OFFSET);
473
+ } else {
474
+ zip64EoCDLocatorOffset = 0n;
392
475
  }
393
476
  return {
394
477
  cdRecordsNumber,
395
- cdStartOffset
478
+ cdStartOffset,
479
+ offsets: {
480
+ zip64EoCDOffset,
481
+ zip64EoCDLocatorOffset,
482
+ zipEoCDOffset
483
+ }
396
484
  };
397
485
  };
486
+ async function updateEoCD(eocdBody, oldEoCDOffsets, newCDStartOffset, eocdStartOffset, newCDRecordsNumber) {
487
+ const eocd = new DataView(eocdBody);
488
+ const classicEoCDOffset = oldEoCDOffsets.zip64EoCDOffset ? oldEoCDOffsets.zipEoCDOffset - oldEoCDOffsets.zip64EoCDOffset : 0n;
489
+ if (Number(newCDRecordsNumber) <= 65535) {
490
+ setFieldToNumber(eocd, 2, classicEoCDOffset + CD_RECORDS_NUMBER_OFFSET, newCDRecordsNumber);
491
+ setFieldToNumber(
492
+ eocd,
493
+ 2,
494
+ classicEoCDOffset + CD_RECORDS_NUMBER_ON_DISC_OFFSET,
495
+ newCDRecordsNumber
496
+ );
497
+ }
498
+ if (eocdStartOffset - newCDStartOffset <= 4294967295) {
499
+ setFieldToNumber(
500
+ eocd,
501
+ 4,
502
+ classicEoCDOffset + CD_CD_BYTE_SIZE_OFFSET,
503
+ eocdStartOffset - newCDStartOffset
504
+ );
505
+ }
506
+ if (newCDStartOffset < 4294967295) {
507
+ setFieldToNumber(eocd, 4, classicEoCDOffset + CD_START_OFFSET_OFFSET, newCDStartOffset);
508
+ }
509
+ if (oldEoCDOffsets.zip64EoCDLocatorOffset && oldEoCDOffsets.zip64EoCDOffset) {
510
+ const locatorOffset = oldEoCDOffsets.zip64EoCDLocatorOffset - oldEoCDOffsets.zip64EoCDOffset;
511
+ setFieldToNumber(eocd, 8, locatorOffset + ZIP64_EOCD_START_OFFSET_OFFSET, eocdStartOffset);
512
+ setFieldToNumber(eocd, 8, ZIP64_CD_START_OFFSET_OFFSET, newCDStartOffset);
513
+ setFieldToNumber(eocd, 8, ZIP64_CD_RECORDS_NUMBER_OFFSET, newCDRecordsNumber);
514
+ setFieldToNumber(eocd, 8, ZIP64_CD_RECORDS_NUMBER_ON_DISC_OFFSET, newCDRecordsNumber);
515
+ setFieldToNumber(eocd, 8, ZIP64_CD_CD_BYTE_SIZE_OFFSET, eocdStartOffset - newCDStartOffset);
516
+ }
517
+ return new Uint8Array(eocd.buffer);
518
+ }
398
519
 
399
520
  // src/parse-zip/cd-file-header.ts
400
521
  var CD_COMPRESSED_SIZE_OFFSET = 20n;
@@ -404,10 +525,10 @@ var CD_EXTRA_FIELD_LENGTH_OFFSET = 30n;
404
525
  var CD_START_DISK_OFFSET = 32n;
405
526
  var CD_LOCAL_HEADER_OFFSET_OFFSET = 42n;
406
527
  var CD_FILE_NAME_OFFSET = 46n;
407
- var signature = new Uint8Array([80, 75, 1, 2]);
528
+ var signature2 = new Uint8Array([80, 75, 1, 2]);
408
529
  var parseZipCDFileHeader = async (headerOffset, file) => {
409
530
  const magicBytes = await file.slice(headerOffset, headerOffset + 4n);
410
- if (!(0, import_loader_utils2.compareArrayBuffers)(magicBytes, signature.buffer)) {
531
+ if (!(0, import_loader_utils3.compareArrayBuffers)(magicBytes, signature2.buffer)) {
411
532
  return null;
412
533
  }
413
534
  const compressedSize = BigInt(await file.getUint32(headerOffset + CD_COMPRESSED_SIZE_OFFSET));
@@ -489,19 +610,157 @@ var findExpectedData = (zip64data) => {
489
610
  }
490
611
  return zip64dataList;
491
612
  };
613
+ function generateCDHeader(options) {
614
+ const optionsToUse = {
615
+ ...options,
616
+ fnlength: options.fileName.length,
617
+ extraLength: 0
618
+ };
619
+ let zip64header = new ArrayBuffer(0);
620
+ const optionsToZip64 = {};
621
+ if (optionsToUse.offset >= 4294967295) {
622
+ optionsToZip64.offset = optionsToUse.offset;
623
+ optionsToUse.offset = BigInt(4294967295);
624
+ }
625
+ if (optionsToUse.length >= 4294967295) {
626
+ optionsToZip64.size = optionsToUse.length;
627
+ optionsToUse.length = 4294967295;
628
+ }
629
+ if (Object.keys(optionsToZip64).length) {
630
+ zip64header = createZip64Info(optionsToZip64);
631
+ optionsToUse.extraLength = zip64header.byteLength;
632
+ }
633
+ const header = new DataView(new ArrayBuffer(Number(CD_FILE_NAME_OFFSET)));
634
+ for (const field of ZIP_HEADER_FIELDS) {
635
+ setFieldToNumber(
636
+ header,
637
+ field.size,
638
+ field.offset,
639
+ optionsToUse[field.name ?? ""] ?? field.default ?? 0
640
+ );
641
+ }
642
+ const encodedName = new TextEncoder().encode(optionsToUse.fileName);
643
+ const resHeader = (0, import_loader_utils3.concatenateArrayBuffers)(header.buffer, encodedName, zip64header);
644
+ return resHeader;
645
+ }
646
+ var ZIP_HEADER_FIELDS = [
647
+ // Central directory file header signature = 0x02014b50
648
+ {
649
+ offset: 0,
650
+ size: 4,
651
+ default: new DataView(signature2.buffer).getUint32(0, true)
652
+ },
653
+ // Version made by
654
+ {
655
+ offset: 4,
656
+ size: 2,
657
+ default: 45
658
+ },
659
+ // Version needed to extract (minimum)
660
+ {
661
+ offset: 6,
662
+ size: 2,
663
+ default: 45
664
+ },
665
+ // General purpose bit flag
666
+ {
667
+ offset: 8,
668
+ size: 2,
669
+ default: 0
670
+ },
671
+ // Compression method
672
+ {
673
+ offset: 10,
674
+ size: 2,
675
+ default: 0
676
+ },
677
+ // File last modification time
678
+ {
679
+ offset: 12,
680
+ size: 2,
681
+ default: 0
682
+ },
683
+ // File last modification date
684
+ {
685
+ offset: 14,
686
+ size: 2,
687
+ default: 0
688
+ },
689
+ // CRC-32 of uncompressed data
690
+ {
691
+ offset: 16,
692
+ size: 4,
693
+ name: "crc32"
694
+ },
695
+ // Compressed size (or 0xffffffff for ZIP64)
696
+ {
697
+ offset: 20,
698
+ size: 4,
699
+ name: "length"
700
+ },
701
+ // Uncompressed size (or 0xffffffff for ZIP64)
702
+ {
703
+ offset: 24,
704
+ size: 4,
705
+ name: "length"
706
+ },
707
+ // File name length (n)
708
+ {
709
+ offset: 28,
710
+ size: 2,
711
+ name: "fnlength"
712
+ },
713
+ // Extra field length (m)
714
+ {
715
+ offset: 30,
716
+ size: 2,
717
+ default: 0,
718
+ name: "extraLength"
719
+ },
720
+ // File comment length (k)
721
+ {
722
+ offset: 32,
723
+ size: 2,
724
+ default: 0
725
+ },
726
+ // Disk number where file starts (or 0xffff for ZIP64)
727
+ {
728
+ offset: 34,
729
+ size: 2,
730
+ default: 0
731
+ },
732
+ // Internal file attributes
733
+ {
734
+ offset: 36,
735
+ size: 2,
736
+ default: 0
737
+ },
738
+ // External file attributes
739
+ {
740
+ offset: 38,
741
+ size: 4,
742
+ default: 0
743
+ },
744
+ // Relative offset of local file header
745
+ {
746
+ offset: 42,
747
+ size: 4,
748
+ name: "offset"
749
+ }
750
+ ];
492
751
 
493
752
  // src/parse-zip/local-file-header.ts
494
- var import_loader_utils3 = require("@loaders.gl/loader-utils");
753
+ var import_loader_utils4 = require("@loaders.gl/loader-utils");
495
754
  var COMPRESSION_METHOD_OFFSET = 8n;
496
755
  var COMPRESSED_SIZE_OFFSET = 18n;
497
756
  var UNCOMPRESSED_SIZE_OFFSET = 22n;
498
757
  var FILE_NAME_LENGTH_OFFSET = 26n;
499
758
  var EXTRA_FIELD_LENGTH_OFFSET = 28n;
500
759
  var FILE_NAME_OFFSET = 30n;
501
- var signature2 = new Uint8Array([80, 75, 3, 4]);
760
+ var signature3 = new Uint8Array([80, 75, 3, 4]);
502
761
  var parseZipLocalFileHeader = async (headerOffset, buffer) => {
503
762
  const magicBytes = await buffer.slice(headerOffset, headerOffset + 4n);
504
- if (!(0, import_loader_utils3.compareArrayBuffers)(magicBytes, signature2)) {
763
+ if (!(0, import_loader_utils4.compareArrayBuffers)(magicBytes, signature3)) {
505
764
  return null;
506
765
  }
507
766
  const fileNameLength = await buffer.getUint16(headerOffset + FILE_NAME_LENGTH_OFFSET);
@@ -538,9 +797,162 @@ var parseZipLocalFileHeader = async (headerOffset, buffer) => {
538
797
  compressionMethod
539
798
  };
540
799
  };
800
+ function generateLocalHeader(options) {
801
+ const optionsToUse = {
802
+ ...options,
803
+ extraLength: 0,
804
+ fnlength: options.fileName.length
805
+ };
806
+ let zip64header = new ArrayBuffer(0);
807
+ const optionsToZip64 = {};
808
+ if (optionsToUse.length >= 4294967295) {
809
+ optionsToZip64.size = optionsToUse.length;
810
+ optionsToUse.length = 4294967295;
811
+ }
812
+ if (Object.keys(optionsToZip64).length) {
813
+ zip64header = createZip64Info(optionsToZip64);
814
+ optionsToUse.extraLength = zip64header.byteLength;
815
+ }
816
+ const header = new DataView(new ArrayBuffer(Number(FILE_NAME_OFFSET)));
817
+ for (const field of ZIP_HEADER_FIELDS2) {
818
+ setFieldToNumber(
819
+ header,
820
+ field.size,
821
+ field.offset,
822
+ optionsToUse[field.name ?? ""] ?? field.default ?? 0
823
+ );
824
+ }
825
+ const encodedName = new TextEncoder().encode(optionsToUse.fileName);
826
+ const resHeader = (0, import_loader_utils4.concatenateArrayBuffers)(header.buffer, encodedName, zip64header);
827
+ return resHeader;
828
+ }
829
+ var ZIP_HEADER_FIELDS2 = [
830
+ // Local file header signature = 0x04034b50
831
+ {
832
+ offset: 0,
833
+ size: 4,
834
+ default: new DataView(signature3.buffer).getUint32(0, true)
835
+ },
836
+ // Version needed to extract (minimum)
837
+ {
838
+ offset: 4,
839
+ size: 2,
840
+ default: 45
841
+ },
842
+ // General purpose bit flag
843
+ {
844
+ offset: 6,
845
+ size: 2,
846
+ default: 0
847
+ },
848
+ // Compression method
849
+ {
850
+ offset: 8,
851
+ size: 2,
852
+ default: 0
853
+ },
854
+ // File last modification time
855
+ {
856
+ offset: 10,
857
+ size: 2,
858
+ default: 0
859
+ },
860
+ // File last modification date
861
+ {
862
+ offset: 12,
863
+ size: 2,
864
+ default: 0
865
+ },
866
+ // CRC-32 of uncompressed data
867
+ {
868
+ offset: 14,
869
+ size: 4,
870
+ name: "crc32"
871
+ },
872
+ // Compressed size (or 0xffffffff for ZIP64)
873
+ {
874
+ offset: 18,
875
+ size: 4,
876
+ name: "length"
877
+ },
878
+ // Uncompressed size (or 0xffffffff for ZIP64)
879
+ {
880
+ offset: 22,
881
+ size: 4,
882
+ name: "length"
883
+ },
884
+ // File name length (n)
885
+ {
886
+ offset: 26,
887
+ size: 2,
888
+ name: "fnlength"
889
+ },
890
+ // Extra field length (m)
891
+ {
892
+ offset: 28,
893
+ size: 2,
894
+ default: 0,
895
+ name: "extraLength"
896
+ }
897
+ ];
541
898
 
542
- // src/hash-file-utility.ts
899
+ // src/parse-zip/zip-compozition.ts
900
+ var import_loader_utils5 = require("@loaders.gl/loader-utils");
543
901
  var import_crypto = require("@loaders.gl/crypto");
902
+ async function cutTheTailOff(provider) {
903
+ const oldEoCDinfo = await parseEoCDRecord(provider);
904
+ const oldCDStartOffset = oldEoCDinfo.cdStartOffset;
905
+ const oldCDLength = Number(
906
+ oldEoCDinfo.offsets.zip64EoCDOffset ? oldEoCDinfo.offsets.zip64EoCDOffset - oldCDStartOffset : oldEoCDinfo.offsets.zipEoCDOffset - oldCDStartOffset
907
+ );
908
+ const zipEnding = await provider.slice(oldCDStartOffset, provider.length);
909
+ await provider.truncate(Number(oldCDStartOffset));
910
+ const oldCDBody = zipEnding.slice(0, oldCDLength);
911
+ const eocdBody = zipEnding.slice(oldCDLength, zipEnding.byteLength);
912
+ return [oldCDBody, eocdBody, oldEoCDinfo];
913
+ }
914
+ async function generateFileHeaders(fileName, fileToAdd, localFileHeaderOffset) {
915
+ const newFileCRC322 = parseInt(await new import_crypto.CRC32Hash().hash(fileToAdd, "hex"), 16);
916
+ const newFileLocalHeader = generateLocalHeader({
917
+ crc32: newFileCRC322,
918
+ fileName,
919
+ length: fileToAdd.byteLength
920
+ });
921
+ const newFileCDHeader = generateCDHeader({
922
+ crc32: newFileCRC322,
923
+ fileName,
924
+ offset: localFileHeaderOffset,
925
+ length: fileToAdd.byteLength
926
+ });
927
+ return [
928
+ new Uint8Array((0, import_loader_utils5.concatenateArrayBuffers)(newFileLocalHeader, fileToAdd)),
929
+ new Uint8Array(newFileCDHeader)
930
+ ];
931
+ }
932
+ async function addOneFile(zipUrl, fileToAdd, fileName) {
933
+ const provider = new import_loader_utils5.FileHandleFile(zipUrl, true);
934
+ const [oldCDBody, eocdBody, oldEoCDinfo] = await cutTheTailOff(provider);
935
+ const newFileOffset = provider.length;
936
+ const [localPart, cdHeaderPart] = await generateFileHeaders(fileName, fileToAdd, newFileOffset);
937
+ await provider.append(localPart);
938
+ const newCDBody = (0, import_loader_utils5.concatenateArrayBuffers)(oldCDBody, cdHeaderPart);
939
+ const newCDStartOffset = provider.length;
940
+ await provider.append(new Uint8Array(newCDBody));
941
+ const eocdOffset = provider.length;
942
+ await provider.append(
943
+ await updateEoCD(
944
+ eocdBody,
945
+ oldEoCDinfo.offsets,
946
+ newCDStartOffset,
947
+ eocdOffset,
948
+ oldEoCDinfo.cdRecordsNumber + 1n
949
+ )
950
+ );
951
+ }
952
+
953
+ // src/hash-file-utility.ts
954
+ var import_crypto2 = require("@loaders.gl/crypto");
955
+ var import_loader_utils6 = require("@loaders.gl/loader-utils");
544
956
  function parseHashTable(arrayBuffer) {
545
957
  const dataView = new DataView(arrayBuffer);
546
958
  const hashMap = {};
@@ -556,7 +968,7 @@ function bufferToHex(buffer, start, length) {
556
968
  }
557
969
  async function makeHashTableFromZipHeaders(fileProvider) {
558
970
  const zipCDIterator = makeZipCDHeaderIterator(fileProvider);
559
- const md5Hash = new import_crypto.MD5Hash();
971
+ const md5Hash = new import_crypto2.MD5Hash();
560
972
  const textEncoder = new TextEncoder();
561
973
  const hashTable = {};
562
974
  for await (const cdHeader of zipCDIterator) {
@@ -567,11 +979,29 @@ async function makeHashTableFromZipHeaders(fileProvider) {
567
979
  }
568
980
  return hashTable;
569
981
  }
982
+ async function composeHashFile(fileProvider) {
983
+ const hashArray = await makeHashTableFromZipHeaders(fileProvider);
984
+ const bufferArray = Object.entries(hashArray).map(([key, value]) => (0, import_loader_utils6.concatenateArrayBuffers)(hexStringToBuffer(key), bigintToBuffer(value))).sort(compareHashes);
985
+ return (0, import_loader_utils6.concatenateArrayBuffersFromArray)(bufferArray);
986
+ }
987
+ function compareHashes(arrA, arrB) {
988
+ const a = new BigUint64Array(arrA);
989
+ const b = new BigUint64Array(arrB);
990
+ return Number(a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]);
991
+ }
992
+ function hexStringToBuffer(str) {
993
+ var _a;
994
+ const byteArray = (_a = str.match(/../g)) == null ? void 0 : _a.map((h) => parseInt(h, 16));
995
+ return new Uint8Array(byteArray ?? new Array(16)).buffer;
996
+ }
997
+ function bigintToBuffer(n) {
998
+ return new BigUint64Array([n]).buffer;
999
+ }
570
1000
 
571
1001
  // src/filesystems/zip-filesystem.ts
572
- var import_loader_utils4 = require("@loaders.gl/loader-utils");
573
- var import_loader_utils5 = require("@loaders.gl/loader-utils");
574
- var import_loader_utils6 = require("@loaders.gl/loader-utils");
1002
+ var import_loader_utils7 = require("@loaders.gl/loader-utils");
1003
+ var import_loader_utils8 = require("@loaders.gl/loader-utils");
1004
+ var import_loader_utils9 = require("@loaders.gl/loader-utils");
575
1005
  var import_compression = require("@loaders.gl/compression");
576
1006
  var COMPRESSION_METHODS = {
577
1007
  /** No compression */
@@ -593,12 +1023,12 @@ var ZipFileSystem = class {
593
1023
  this.fileProvider = null;
594
1024
  if (typeof file === "string") {
595
1025
  this.fileName = file;
596
- if (!import_loader_utils4.isBrowser) {
597
- this.fileProvider = new import_loader_utils6.FileHandleFile(file);
1026
+ if (!import_loader_utils7.isBrowser) {
1027
+ this.fileProvider = new import_loader_utils9.FileHandleFile(file);
598
1028
  } else {
599
1029
  throw new Error("Cannot open file for random access in a WEB browser");
600
1030
  }
601
- } else if ((0, import_loader_utils5.isFileProvider)(file)) {
1031
+ } else if ((0, import_loader_utils8.isFileProvider)(file)) {
602
1032
  this.fileProvider = file;
603
1033
  }
604
1034
  }