@loaders.gl/zip 4.0.0-beta.2 → 4.0.0-beta.4

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 (105) hide show
  1. package/dist/{dist.min.js → dist.dev.js} +1929 -1728
  2. package/dist/filesystems/zip-filesystem.d.ts +1 -1
  3. package/dist/filesystems/zip-filesystem.d.ts.map +1 -1
  4. package/dist/{esm/filesystems → filesystems}/zip-filesystem.js +16 -21
  5. package/dist/filesystems/zip-filesystem.js.map +1 -0
  6. package/dist/hash-file-utility.d.ts +5 -26
  7. package/dist/hash-file-utility.d.ts.map +1 -1
  8. package/dist/hash-file-utility.js +29 -0
  9. package/dist/hash-file-utility.js.map +1 -0
  10. package/dist/index.cjs +653 -0
  11. package/dist/index.d.ts +2 -3
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +10 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/{esm/lib → lib}/tar/header.js +1 -1
  16. package/dist/lib/tar/header.js.map +1 -0
  17. package/dist/{esm/lib → lib}/tar/tar.js +8 -9
  18. package/dist/lib/tar/tar.js.map +1 -0
  19. package/dist/lib/tar/types.js.map +1 -0
  20. package/dist/lib/tar/utils.js.map +1 -0
  21. package/dist/parse-zip/cd-file-header.d.ts +2 -2
  22. package/dist/parse-zip/cd-file-header.d.ts.map +1 -1
  23. package/dist/parse-zip/cd-file-header.js +57 -0
  24. package/dist/parse-zip/cd-file-header.js.map +1 -0
  25. package/dist/parse-zip/end-of-central-directory.d.ts +2 -2
  26. package/dist/parse-zip/end-of-central-directory.d.ts.map +1 -1
  27. package/dist/parse-zip/end-of-central-directory.js +34 -0
  28. package/dist/parse-zip/end-of-central-directory.js.map +1 -0
  29. package/dist/parse-zip/local-file-header.d.ts +2 -1
  30. package/dist/parse-zip/local-file-header.d.ts.map +1 -1
  31. package/dist/{esm/parse-zip → parse-zip}/local-file-header.js +4 -2
  32. package/dist/parse-zip/local-file-header.js.map +1 -0
  33. package/dist/parse-zip/search-from-the-end.d.ts +1 -1
  34. package/dist/parse-zip/search-from-the-end.d.ts.map +1 -1
  35. package/dist/parse-zip/search-from-the-end.js.map +1 -0
  36. package/dist/{esm/tar-builder.js → tar-builder.js} +4 -5
  37. package/dist/tar-builder.js.map +1 -0
  38. package/dist/{esm/zip-loader.js → zip-loader.js} +3 -3
  39. package/dist/zip-loader.js.map +1 -0
  40. package/dist/{esm/zip-writer.js → zip-writer.js} +1 -1
  41. package/dist/zip-writer.js.map +1 -0
  42. package/package.json +17 -8
  43. package/src/filesystems/zip-filesystem.ts +13 -17
  44. package/src/hash-file-utility.ts +37 -85
  45. package/src/index.ts +3 -3
  46. package/src/parse-zip/cd-file-header.ts +20 -27
  47. package/src/parse-zip/end-of-central-directory.ts +16 -26
  48. package/src/parse-zip/local-file-header.ts +5 -7
  49. package/src/parse-zip/search-from-the-end.ts +1 -1
  50. package/dist/bundle.d.ts +0 -2
  51. package/dist/bundle.d.ts.map +0 -1
  52. package/dist/es5/bundle.js +0 -6
  53. package/dist/es5/bundle.js.map +0 -1
  54. package/dist/es5/filesystems/zip-filesystem.js +0 -372
  55. package/dist/es5/filesystems/zip-filesystem.js.map +0 -1
  56. package/dist/es5/hash-file-utility.js +0 -130
  57. package/dist/es5/hash-file-utility.js.map +0 -1
  58. package/dist/es5/index.js +0 -105
  59. package/dist/es5/index.js.map +0 -1
  60. package/dist/es5/lib/tar/header.js +0 -52
  61. package/dist/es5/lib/tar/header.js.map +0 -1
  62. package/dist/es5/lib/tar/tar.js +0 -137
  63. package/dist/es5/lib/tar/tar.js.map +0 -1
  64. package/dist/es5/lib/tar/types.js +0 -2
  65. package/dist/es5/lib/tar/types.js.map +0 -1
  66. package/dist/es5/lib/tar/utils.js +0 -32
  67. package/dist/es5/lib/tar/utils.js.map +0 -1
  68. package/dist/es5/parse-zip/cd-file-header.js +0 -163
  69. package/dist/es5/parse-zip/cd-file-header.js.map +0 -1
  70. package/dist/es5/parse-zip/end-of-central-directory.js +0 -98
  71. package/dist/es5/parse-zip/end-of-central-directory.js.map +0 -1
  72. package/dist/es5/parse-zip/local-file-header.js +0 -117
  73. package/dist/es5/parse-zip/local-file-header.js.map +0 -1
  74. package/dist/es5/parse-zip/search-from-the-end.js +0 -69
  75. package/dist/es5/parse-zip/search-from-the-end.js.map +0 -1
  76. package/dist/es5/tar-builder.js +0 -69
  77. package/dist/es5/tar-builder.js.map +0 -1
  78. package/dist/es5/zip-loader.js +0 -103
  79. package/dist/es5/zip-loader.js.map +0 -1
  80. package/dist/es5/zip-writer.js +0 -66
  81. package/dist/es5/zip-writer.js.map +0 -1
  82. package/dist/esm/bundle.js +0 -4
  83. package/dist/esm/bundle.js.map +0 -1
  84. package/dist/esm/filesystems/zip-filesystem.js.map +0 -1
  85. package/dist/esm/hash-file-utility.js +0 -55
  86. package/dist/esm/hash-file-utility.js.map +0 -1
  87. package/dist/esm/index.js +0 -10
  88. package/dist/esm/index.js.map +0 -1
  89. package/dist/esm/lib/tar/header.js.map +0 -1
  90. package/dist/esm/lib/tar/tar.js.map +0 -1
  91. package/dist/esm/lib/tar/types.js.map +0 -1
  92. package/dist/esm/lib/tar/utils.js.map +0 -1
  93. package/dist/esm/parse-zip/cd-file-header.js +0 -54
  94. package/dist/esm/parse-zip/cd-file-header.js.map +0 -1
  95. package/dist/esm/parse-zip/end-of-central-directory.js +0 -31
  96. package/dist/esm/parse-zip/end-of-central-directory.js.map +0 -1
  97. package/dist/esm/parse-zip/local-file-header.js.map +0 -1
  98. package/dist/esm/parse-zip/search-from-the-end.js.map +0 -1
  99. package/dist/esm/tar-builder.js.map +0 -1
  100. package/dist/esm/zip-loader.js.map +0 -1
  101. package/dist/esm/zip-writer.js.map +0 -1
  102. package/src/bundle.ts +0 -4
  103. /package/dist/{esm/lib → lib}/tar/types.js +0 -0
  104. /package/dist/{esm/lib → lib}/tar/utils.js +0 -0
  105. /package/dist/{esm/parse-zip → parse-zip}/search-from-the-end.js +0 -0
package/dist/index.cjs ADDED
@@ -0,0 +1,653 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ TarBuilder: () => TarBuilder,
34
+ ZipFileSystem: () => ZipFileSystem,
35
+ ZipLoader: () => ZipLoader,
36
+ ZipWriter: () => ZipWriter,
37
+ cdSignature: () => signature,
38
+ localHeaderSignature: () => signature2,
39
+ makeHashTableFromZipHeaders: () => makeHashTableFromZipHeaders,
40
+ makeZipCDHeaderIterator: () => makeZipCDHeaderIterator,
41
+ parseEoCDRecord: () => parseEoCDRecord,
42
+ parseHashTable: () => parseHashTable,
43
+ parseZipCDFileHeader: () => parseZipCDFileHeader,
44
+ parseZipLocalFileHeader: () => parseZipLocalFileHeader,
45
+ searchFromTheEnd: () => searchFromTheEnd
46
+ });
47
+ module.exports = __toCommonJS(src_exports);
48
+
49
+ // src/zip-loader.ts
50
+ var import_jszip = __toESM(require("jszip"), 1);
51
+ var VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
52
+ var ZipLoader = {
53
+ id: "zip",
54
+ module: "zip",
55
+ name: "Zip Archive",
56
+ version: VERSION,
57
+ extensions: ["zip"],
58
+ mimeTypes: ["application/zip"],
59
+ category: "archive",
60
+ tests: ["PK"],
61
+ options: {},
62
+ parse: parseZipAsync
63
+ };
64
+ async function parseZipAsync(data, options = {}) {
65
+ const promises = [];
66
+ const fileMap = {};
67
+ try {
68
+ const jsZip = new import_jszip.default();
69
+ const zip = await jsZip.loadAsync(data, options);
70
+ zip.forEach((relativePath, zipEntry) => {
71
+ const subFilename = zipEntry.name;
72
+ const promise = loadZipEntry(jsZip, subFilename, options).then((arrayBufferOrError) => {
73
+ fileMap[relativePath] = arrayBufferOrError;
74
+ });
75
+ promises.push(promise);
76
+ });
77
+ await Promise.all(promises);
78
+ return fileMap;
79
+ } catch (error) {
80
+ options.log.error(`Unable to read zip archive: ${error}`);
81
+ throw error;
82
+ }
83
+ }
84
+ async function loadZipEntry(jsZip, subFilename, options = {}) {
85
+ try {
86
+ const arrayBuffer = await jsZip.file(subFilename).async(options.dataType || "arraybuffer");
87
+ return arrayBuffer;
88
+ } catch (error) {
89
+ options.log.error(`Unable to read ${subFilename} from zip archive: ${error}`);
90
+ return error;
91
+ }
92
+ }
93
+
94
+ // src/zip-writer.ts
95
+ var import_jszip2 = __toESM(require("jszip"), 1);
96
+ var ZipWriter = {
97
+ name: "Zip Archive",
98
+ extensions: ["zip"],
99
+ category: "archive",
100
+ mimeTypes: ["application/zip"],
101
+ // @ts-ignore
102
+ encode: encodeZipAsync
103
+ };
104
+ async function encodeZipAsync(fileMap, options = {}) {
105
+ const jsZip = new import_jszip2.default();
106
+ for (const subFileName in fileMap) {
107
+ const subFileData = fileMap[subFileName];
108
+ jsZip.file(subFileName, subFileData, (options == null ? void 0 : options.jszip) || {});
109
+ }
110
+ const jszipOptions = { ...options == null ? void 0 : options.jszip, type: "arraybuffer" };
111
+ const { onUpdate = () => {
112
+ } } = options;
113
+ try {
114
+ return await jsZip.generateAsync(jszipOptions, onUpdate);
115
+ } catch (error) {
116
+ options.log.error(`Unable to write zip archive: ${error}`);
117
+ throw error;
118
+ }
119
+ }
120
+
121
+ // src/lib/tar/utils.ts
122
+ function clean(length) {
123
+ let i;
124
+ const buffer = new Uint8Array(length);
125
+ for (i = 0; i < length; i += 1) {
126
+ buffer[i] = 0;
127
+ }
128
+ return buffer;
129
+ }
130
+ function pad(num, bytes, base) {
131
+ const numStr = num.toString(base || 8);
132
+ return "000000000000".substr(numStr.length + 12 - bytes) + numStr;
133
+ }
134
+ function stringToUint8(input, out, offset) {
135
+ let i;
136
+ let length;
137
+ out = out || clean(input.length);
138
+ offset = offset || 0;
139
+ for (i = 0, length = input.length; i < length; i += 1) {
140
+ out[offset] = input.charCodeAt(i);
141
+ offset += 1;
142
+ }
143
+ return out;
144
+ }
145
+
146
+ // src/lib/tar/header.ts
147
+ var structure = {
148
+ fileName: 100,
149
+ fileMode: 8,
150
+ uid: 8,
151
+ gid: 8,
152
+ fileSize: 12,
153
+ mtime: 12,
154
+ checksum: 8,
155
+ type: 1,
156
+ linkName: 100,
157
+ ustar: 8,
158
+ owner: 32,
159
+ group: 32,
160
+ majorNumber: 8,
161
+ minorNumber: 8,
162
+ filenamePrefix: 155,
163
+ padding: 12
164
+ };
165
+ function format(data, cb) {
166
+ const buffer = clean(512);
167
+ let offset = 0;
168
+ Object.entries(structure).forEach(([field, length]) => {
169
+ const str = data[field] || "";
170
+ let i;
171
+ let fieldLength;
172
+ for (i = 0, fieldLength = str.length; i < fieldLength; i += 1) {
173
+ buffer[offset] = str.charCodeAt(i);
174
+ offset += 1;
175
+ }
176
+ offset += length - i;
177
+ });
178
+ if (typeof cb === "function") {
179
+ return cb(buffer, offset);
180
+ }
181
+ return buffer;
182
+ }
183
+
184
+ // src/lib/tar/tar.ts
185
+ var blockSize;
186
+ var headerLength;
187
+ var inputLength;
188
+ var recordSize = 512;
189
+ var Tar = class {
190
+ /**
191
+ * @param [recordsPerBlock]
192
+ */
193
+ constructor(recordsPerBlock) {
194
+ this.blocks = [];
195
+ this.written = 0;
196
+ blockSize = (recordsPerBlock || 20) * recordSize;
197
+ this.out = clean(blockSize);
198
+ this.blocks = [];
199
+ this.length = 0;
200
+ this.save = this.save.bind(this);
201
+ this.clear = this.clear.bind(this);
202
+ this.append = this.append.bind(this);
203
+ }
204
+ /**
205
+ * Append a file to the tar archive
206
+ * @param filepath
207
+ * @param input
208
+ * @param [opts]
209
+ */
210
+ // eslint-disable-next-line complexity
211
+ append(filepath, input, opts) {
212
+ let checksum;
213
+ if (typeof input === "string") {
214
+ input = stringToUint8(input);
215
+ } else if (input.constructor && input.constructor !== Uint8Array.prototype.constructor) {
216
+ const errorInputMatch = /function\s*([$A-Za-z_][0-9A-Za-z_]*)\s*\(/.exec(
217
+ input.constructor.toString()
218
+ );
219
+ const errorInput = errorInputMatch && errorInputMatch[1];
220
+ const errorMessage = `Invalid input type. You gave me: ${errorInput}`;
221
+ throw errorMessage;
222
+ }
223
+ opts = opts || {};
224
+ const mode = opts.mode || parseInt("777", 8) & 4095;
225
+ const mtime = opts.mtime || Math.floor(Number(new Date()) / 1e3);
226
+ const uid = opts.uid || 0;
227
+ const gid = opts.gid || 0;
228
+ const data = {
229
+ fileName: filepath,
230
+ fileMode: pad(mode, 7),
231
+ uid: pad(uid, 7),
232
+ gid: pad(gid, 7),
233
+ fileSize: pad(input.length, 11),
234
+ mtime: pad(mtime, 11),
235
+ checksum: " ",
236
+ // 0 = just a file
237
+ type: "0",
238
+ ustar: "ustar ",
239
+ owner: opts.owner || "",
240
+ group: opts.group || ""
241
+ };
242
+ checksum = 0;
243
+ Object.keys(data).forEach((key) => {
244
+ let i;
245
+ const value = data[key];
246
+ let length;
247
+ for (i = 0, length = value.length; i < length; i += 1) {
248
+ checksum += value.charCodeAt(i);
249
+ }
250
+ });
251
+ data.checksum = `${pad(checksum, 6)}\0 `;
252
+ const headerArr = format(data);
253
+ headerLength = Math.ceil(headerArr.length / recordSize) * recordSize;
254
+ inputLength = Math.ceil(input.length / recordSize) * recordSize;
255
+ this.blocks.push({
256
+ header: headerArr,
257
+ input,
258
+ headerLength,
259
+ inputLength
260
+ });
261
+ }
262
+ /**
263
+ * Compiling data to a Blob object
264
+ * @returns {Blob}
265
+ */
266
+ save() {
267
+ const buffers = [];
268
+ const chunks = new Array();
269
+ let length = 0;
270
+ const max = Math.pow(2, 20);
271
+ let chunk = new Array();
272
+ this.blocks.forEach((b = []) => {
273
+ if (length + b.headerLength + b.inputLength > max) {
274
+ chunks.push({ blocks: chunk, length });
275
+ chunk = [];
276
+ length = 0;
277
+ }
278
+ chunk.push(b);
279
+ length += b.headerLength + b.inputLength;
280
+ });
281
+ chunks.push({ blocks: chunk, length });
282
+ chunks.forEach((c = []) => {
283
+ const buffer = new Uint8Array(c.length);
284
+ let written = 0;
285
+ c.blocks.forEach((b = []) => {
286
+ buffer.set(b.header, written);
287
+ written += b.headerLength;
288
+ buffer.set(b.input, written);
289
+ written += b.inputLength;
290
+ });
291
+ buffers.push(buffer);
292
+ });
293
+ buffers.push(new Uint8Array(2 * recordSize));
294
+ return new Blob(buffers, { type: "octet/stream" });
295
+ }
296
+ /**
297
+ * Clear the data by its blocksize
298
+ */
299
+ clear() {
300
+ this.written = 0;
301
+ this.out = clean(blockSize);
302
+ }
303
+ };
304
+ var tar_default = Tar;
305
+
306
+ // src/tar-builder.ts
307
+ var TAR_BUILDER_OPTIONS = {
308
+ recordsPerBlock: 20
309
+ };
310
+ var TarBuilder = class {
311
+ constructor(options) {
312
+ this.count = 0;
313
+ this.options = { ...TAR_BUILDER_OPTIONS, ...options };
314
+ this.tape = new tar_default(this.options.recordsPerBlock);
315
+ }
316
+ static get properties() {
317
+ return {
318
+ id: "tar",
319
+ name: "TAR",
320
+ extensions: ["tar"],
321
+ mimeTypes: ["application/x-tar"],
322
+ builder: TarBuilder,
323
+ options: TAR_BUILDER_OPTIONS
324
+ };
325
+ }
326
+ /** Adds a file to the archive. */
327
+ addFile(filename, buffer) {
328
+ this.tape.append(filename, new Uint8Array(buffer));
329
+ this.count++;
330
+ }
331
+ async build() {
332
+ return new Response(this.tape.save()).arrayBuffer();
333
+ }
334
+ };
335
+
336
+ // src/parse-zip/cd-file-header.ts
337
+ var import_loader_utils2 = require("@loaders.gl/loader-utils");
338
+
339
+ // src/parse-zip/end-of-central-directory.ts
340
+ var import_loader_utils = require("@loaders.gl/loader-utils");
341
+
342
+ // src/parse-zip/search-from-the-end.ts
343
+ var searchFromTheEnd = async (file, target) => {
344
+ const searchWindow = [
345
+ await file.getUint8(file.length - 1n),
346
+ await file.getUint8(file.length - 2n),
347
+ await file.getUint8(file.length - 3n),
348
+ void 0
349
+ ];
350
+ let targetOffset = 0n;
351
+ for (let i = file.length - 4n; i > -1; i--) {
352
+ searchWindow[3] = searchWindow[2];
353
+ searchWindow[2] = searchWindow[1];
354
+ searchWindow[1] = searchWindow[0];
355
+ searchWindow[0] = await file.getUint8(i);
356
+ if (searchWindow.every((val, index) => val === target[index])) {
357
+ targetOffset = i;
358
+ break;
359
+ }
360
+ }
361
+ return targetOffset;
362
+ };
363
+
364
+ // src/parse-zip/end-of-central-directory.ts
365
+ var eoCDSignature = new Uint8Array([80, 75, 5, 6]);
366
+ var zip64EoCDLocatorSignature = new Uint8Array([80, 75, 6, 7]);
367
+ var zip64EoCDSignature = new Uint8Array([80, 75, 6, 6]);
368
+ var CD_RECORDS_NUMBER_OFFSET = 8n;
369
+ var CD_START_OFFSET_OFFSET = 16n;
370
+ var ZIP64_EOCD_START_OFFSET_OFFSET = 8n;
371
+ var ZIP64_CD_RECORDS_NUMBER_OFFSET = 24n;
372
+ var ZIP64_CD_START_OFFSET_OFFSET = 48n;
373
+ var parseEoCDRecord = async (file) => {
374
+ const zipEoCDOffset = await searchFromTheEnd(file, eoCDSignature);
375
+ let cdRecordsNumber = BigInt(await file.getUint16(zipEoCDOffset + CD_RECORDS_NUMBER_OFFSET));
376
+ 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(
384
+ zip64EoCDLocatorOffset + ZIP64_EOCD_START_OFFSET_OFFSET
385
+ );
386
+ const endOfCDMagicBytes = await file.slice(zip64EoCDOffset, zip64EoCDOffset + 4n);
387
+ if (!(0, import_loader_utils.compareArrayBuffers)(endOfCDMagicBytes, zip64EoCDSignature.buffer)) {
388
+ throw new Error("zip64 EoCD not found");
389
+ }
390
+ cdRecordsNumber = await file.getBigUint64(zip64EoCDOffset + ZIP64_CD_RECORDS_NUMBER_OFFSET);
391
+ cdStartOffset = await file.getBigUint64(zip64EoCDOffset + ZIP64_CD_START_OFFSET_OFFSET);
392
+ }
393
+ return {
394
+ cdRecordsNumber,
395
+ cdStartOffset
396
+ };
397
+ };
398
+
399
+ // src/parse-zip/cd-file-header.ts
400
+ var CD_COMPRESSED_SIZE_OFFSET = 20n;
401
+ var CD_UNCOMPRESSED_SIZE_OFFSET = 24n;
402
+ var CD_FILE_NAME_LENGTH_OFFSET = 28n;
403
+ var CD_EXTRA_FIELD_LENGTH_OFFSET = 30n;
404
+ var CD_LOCAL_HEADER_OFFSET_OFFSET = 42n;
405
+ var CD_FILE_NAME_OFFSET = 46n;
406
+ var signature = new Uint8Array([80, 75, 1, 2]);
407
+ var parseZipCDFileHeader = async (headerOffset, file) => {
408
+ const magicBytes = await file.slice(headerOffset, headerOffset + 4n);
409
+ if (!(0, import_loader_utils2.compareArrayBuffers)(magicBytes, signature.buffer)) {
410
+ return null;
411
+ }
412
+ let compressedSize = BigInt(await file.getUint32(headerOffset + CD_COMPRESSED_SIZE_OFFSET));
413
+ let uncompressedSize = BigInt(await file.getUint32(headerOffset + CD_UNCOMPRESSED_SIZE_OFFSET));
414
+ const extraFieldLength = await file.getUint16(headerOffset + CD_EXTRA_FIELD_LENGTH_OFFSET);
415
+ const fileNameLength = await file.getUint16(headerOffset + CD_FILE_NAME_LENGTH_OFFSET);
416
+ const filenameBytes = await file.slice(
417
+ headerOffset + CD_FILE_NAME_OFFSET,
418
+ headerOffset + CD_FILE_NAME_OFFSET + BigInt(fileNameLength)
419
+ );
420
+ const fileName = new TextDecoder().decode(filenameBytes);
421
+ const extraOffset = headerOffset + CD_FILE_NAME_OFFSET + BigInt(fileNameLength);
422
+ const oldFormatOffset = await file.getUint32(headerOffset + CD_LOCAL_HEADER_OFFSET_OFFSET);
423
+ let fileDataOffset = BigInt(oldFormatOffset);
424
+ let offsetInZip64Data = 4n;
425
+ if (uncompressedSize === BigInt(4294967295)) {
426
+ uncompressedSize = await file.getBigUint64(extraOffset + offsetInZip64Data);
427
+ offsetInZip64Data += 8n;
428
+ }
429
+ if (compressedSize === BigInt(4294967295)) {
430
+ compressedSize = await file.getBigUint64(extraOffset + offsetInZip64Data);
431
+ offsetInZip64Data += 8n;
432
+ }
433
+ if (fileDataOffset === BigInt(4294967295)) {
434
+ fileDataOffset = await file.getBigUint64(extraOffset + offsetInZip64Data);
435
+ }
436
+ const localHeaderOffset = fileDataOffset;
437
+ return {
438
+ compressedSize,
439
+ uncompressedSize,
440
+ extraFieldLength,
441
+ fileNameLength,
442
+ fileName,
443
+ extraOffset,
444
+ localHeaderOffset
445
+ };
446
+ };
447
+ async function* makeZipCDHeaderIterator(fileProvider) {
448
+ const { cdStartOffset } = await parseEoCDRecord(fileProvider);
449
+ let cdHeader = await parseZipCDFileHeader(cdStartOffset, fileProvider);
450
+ while (cdHeader) {
451
+ yield cdHeader;
452
+ cdHeader = await parseZipCDFileHeader(
453
+ cdHeader.extraOffset + BigInt(cdHeader.extraFieldLength),
454
+ fileProvider
455
+ );
456
+ }
457
+ }
458
+
459
+ // src/parse-zip/local-file-header.ts
460
+ var import_loader_utils3 = require("@loaders.gl/loader-utils");
461
+ var COMPRESSION_METHOD_OFFSET = 8n;
462
+ var COMPRESSED_SIZE_OFFSET = 18n;
463
+ var UNCOMPRESSED_SIZE_OFFSET = 22n;
464
+ var FILE_NAME_LENGTH_OFFSET = 26n;
465
+ var EXTRA_FIELD_LENGTH_OFFSET = 28n;
466
+ var FILE_NAME_OFFSET = 30n;
467
+ var signature2 = new Uint8Array([80, 75, 3, 4]);
468
+ var parseZipLocalFileHeader = async (headerOffset, buffer) => {
469
+ const magicBytes = await buffer.slice(headerOffset, headerOffset + 4n);
470
+ if (!(0, import_loader_utils3.compareArrayBuffers)(magicBytes, signature2)) {
471
+ return null;
472
+ }
473
+ const fileNameLength = await buffer.getUint16(headerOffset + FILE_NAME_LENGTH_OFFSET);
474
+ const fileName = new TextDecoder().decode(
475
+ await buffer.slice(
476
+ headerOffset + FILE_NAME_OFFSET,
477
+ headerOffset + FILE_NAME_OFFSET + BigInt(fileNameLength)
478
+ )
479
+ ).split("\\").join("/");
480
+ const extraFieldLength = await buffer.getUint16(headerOffset + EXTRA_FIELD_LENGTH_OFFSET);
481
+ let fileDataOffset = headerOffset + FILE_NAME_OFFSET + BigInt(fileNameLength + extraFieldLength);
482
+ const compressionMethod = await buffer.getUint16(headerOffset + COMPRESSION_METHOD_OFFSET);
483
+ let compressedSize = BigInt(await buffer.getUint32(headerOffset + COMPRESSED_SIZE_OFFSET));
484
+ let uncompressedSize = BigInt(await buffer.getUint32(headerOffset + UNCOMPRESSED_SIZE_OFFSET));
485
+ const extraOffset = headerOffset + FILE_NAME_OFFSET + BigInt(fileNameLength);
486
+ let offsetInZip64Data = 4n;
487
+ if (uncompressedSize === BigInt(4294967295)) {
488
+ uncompressedSize = await buffer.getBigUint64(extraOffset + offsetInZip64Data);
489
+ offsetInZip64Data += 8n;
490
+ }
491
+ if (compressedSize === BigInt(4294967295)) {
492
+ compressedSize = await buffer.getBigUint64(extraOffset + offsetInZip64Data);
493
+ offsetInZip64Data += 8n;
494
+ }
495
+ if (fileDataOffset === BigInt(4294967295)) {
496
+ fileDataOffset = await buffer.getBigUint64(extraOffset + offsetInZip64Data);
497
+ }
498
+ return {
499
+ fileNameLength,
500
+ fileName,
501
+ extraFieldLength,
502
+ fileDataOffset,
503
+ compressedSize,
504
+ compressionMethod
505
+ };
506
+ };
507
+
508
+ // src/hash-file-utility.ts
509
+ var import_crypto = require("@loaders.gl/crypto");
510
+ function parseHashTable(arrayBuffer) {
511
+ const dataView = new DataView(arrayBuffer);
512
+ const hashMap = {};
513
+ for (let i = 0; i < arrayBuffer.byteLength; i = i + 24) {
514
+ const offset = dataView.getBigUint64(i + 16, true);
515
+ const hash = bufferToHex(arrayBuffer, i, 16);
516
+ hashMap[hash] = offset;
517
+ }
518
+ return hashMap;
519
+ }
520
+ function bufferToHex(buffer, start, length) {
521
+ return [...new Uint8Array(buffer, start, length)].map((x) => x.toString(16).padStart(2, "0")).join("");
522
+ }
523
+ async function makeHashTableFromZipHeaders(fileProvider) {
524
+ const zipCDIterator = makeZipCDHeaderIterator(fileProvider);
525
+ const md5Hash = new import_crypto.MD5Hash();
526
+ const textEncoder = new TextEncoder();
527
+ const hashTable = {};
528
+ for await (const cdHeader of zipCDIterator) {
529
+ const filename = cdHeader.fileName.split("\\").join("/").toLocaleLowerCase();
530
+ const arrayBuffer = textEncoder.encode(filename).buffer;
531
+ const md5 = await md5Hash.hash(arrayBuffer, "hex");
532
+ hashTable[md5] = cdHeader.localHeaderOffset;
533
+ }
534
+ return hashTable;
535
+ }
536
+
537
+ // src/filesystems/zip-filesystem.ts
538
+ var import_loader_utils4 = require("@loaders.gl/loader-utils");
539
+ var import_loader_utils5 = require("@loaders.gl/loader-utils");
540
+ var import_loader_utils6 = require("@loaders.gl/loader-utils");
541
+ var import_compression = require("@loaders.gl/compression");
542
+ var COMPRESSION_METHODS = {
543
+ /** No compression */
544
+ 0: async (compressedFile) => compressedFile,
545
+ /** Deflation */
546
+ 8: async (compressedFile) => {
547
+ const compression = new import_compression.DeflateCompression({ raw: true });
548
+ const decompressedData = await compression.decompress(compressedFile);
549
+ return decompressedData;
550
+ }
551
+ };
552
+ var ZipFileSystem = class {
553
+ /**
554
+ * Constructor
555
+ * @param file - instance of FileProvider or file path string
556
+ */
557
+ constructor(file) {
558
+ /** FileProvider instance promise */
559
+ this.fileProvider = null;
560
+ if (typeof file === "string") {
561
+ this.fileName = file;
562
+ if (!import_loader_utils4.isBrowser) {
563
+ this.fileProvider = new import_loader_utils6.FileHandleFile(file);
564
+ } else {
565
+ throw new Error("Cannot open file for random access in a WEB browser");
566
+ }
567
+ } else if ((0, import_loader_utils5.isFileProvider)(file)) {
568
+ this.fileProvider = file;
569
+ }
570
+ }
571
+ /** Clean up resources */
572
+ async destroy() {
573
+ if (this.fileProvider) {
574
+ await this.fileProvider.destroy();
575
+ }
576
+ }
577
+ /**
578
+ * Get file names list from zip archive
579
+ * @returns array of file names
580
+ */
581
+ async readdir() {
582
+ if (!this.fileProvider) {
583
+ throw new Error("No data detected in the zip archive");
584
+ }
585
+ const fileNames = [];
586
+ const zipCDIterator = makeZipCDHeaderIterator(this.fileProvider);
587
+ for await (const cdHeader of zipCDIterator) {
588
+ fileNames.push(cdHeader.fileName);
589
+ }
590
+ return fileNames;
591
+ }
592
+ /**
593
+ * Get file metadata
594
+ * @param filename - name of a file
595
+ * @returns central directory data
596
+ */
597
+ async stat(filename) {
598
+ const cdFileHeader = await this.getCDFileHeader(filename);
599
+ return { ...cdFileHeader, size: Number(cdFileHeader.uncompressedSize) };
600
+ }
601
+ /**
602
+ * Implementation of fetch against this file system
603
+ * @param filename - name of a file
604
+ * @returns - Response with file data
605
+ */
606
+ async fetch(filename) {
607
+ if (!this.fileProvider) {
608
+ throw new Error("No data detected in the zip archive");
609
+ }
610
+ const cdFileHeader = await this.getCDFileHeader(filename);
611
+ const localFileHeader = await parseZipLocalFileHeader(
612
+ cdFileHeader.localHeaderOffset,
613
+ this.fileProvider
614
+ );
615
+ if (!localFileHeader) {
616
+ throw new Error("Local file header has not been found in the zip archive`");
617
+ }
618
+ const compressionHandler = COMPRESSION_METHODS[localFileHeader.compressionMethod.toString()];
619
+ if (!compressionHandler) {
620
+ throw Error("Only Deflation compression is supported");
621
+ }
622
+ const compressedFile = await this.fileProvider.slice(
623
+ localFileHeader.fileDataOffset,
624
+ localFileHeader.fileDataOffset + localFileHeader.compressedSize
625
+ );
626
+ const uncompressedFile = await compressionHandler(compressedFile);
627
+ const response = new Response(uncompressedFile);
628
+ Object.defineProperty(response, "url", { value: `${this.fileName || ""}/${filename}` });
629
+ return response;
630
+ }
631
+ /**
632
+ * Get central directory file header
633
+ * @param filename - name of a file
634
+ * @returns central directory file header
635
+ */
636
+ async getCDFileHeader(filename) {
637
+ if (!this.fileProvider) {
638
+ throw new Error("No data detected in the zip archive");
639
+ }
640
+ const zipCDIterator = makeZipCDHeaderIterator(this.fileProvider);
641
+ let result = null;
642
+ for await (const cdHeader of zipCDIterator) {
643
+ if (cdHeader.fileName === filename) {
644
+ result = cdHeader;
645
+ break;
646
+ }
647
+ }
648
+ if (!result) {
649
+ throw new Error("File has not been found in the zip archive");
650
+ }
651
+ return result;
652
+ }
653
+ };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,10 @@
1
1
  export { ZipLoader } from './zip-loader';
2
2
  export { ZipWriter } from './zip-writer';
3
3
  export { TarBuilder } from './tar-builder';
4
- export { parseZipCDFileHeader, zipCDFileHeaderGenerator, signature as cdSignature } from './parse-zip/cd-file-header';
4
+ export { parseZipCDFileHeader, makeZipCDHeaderIterator, signature as cdSignature } from './parse-zip/cd-file-header';
5
5
  export { parseZipLocalFileHeader, signature as localHeaderSignature } from './parse-zip/local-file-header';
6
6
  export { parseEoCDRecord } from './parse-zip/end-of-central-directory';
7
7
  export { searchFromTheEnd } from './parse-zip/search-from-the-end';
8
- export type { HashElement } from './hash-file-utility';
9
- export { compareHashes, parseHashFile, findBin, generateHashInfo } from './hash-file-utility';
8
+ export { parseHashTable, makeHashTableFromZipHeaders } from './hash-file-utility';
10
9
  export { ZipFileSystem } from './filesystems/zip-filesystem';
11
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AACvC,OAAO,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AACvC,OAAO,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAEzC,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,SAAS,IAAI,WAAW,EACzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,uBAAuB,EACvB,SAAS,IAAI,oBAAoB,EAClC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAC,eAAe,EAAC,MAAM,sCAAsC,CAAC;AACrE,OAAO,EAAC,gBAAgB,EAAC,MAAM,iCAAiC,CAAC;AAEjE,YAAY,EAAC,WAAW,EAAC,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAC,aAAa,EAAE,aAAa,EAAE,OAAO,EAAE,gBAAgB,EAAC,MAAM,qBAAqB,CAAC;AAE5F,OAAO,EAAC,aAAa,EAAC,MAAM,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AACvC,OAAO,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AACvC,OAAO,EAAC,UAAU,EAAC,MAAM,eAAe,CAAC;AAEzC,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,SAAS,IAAI,WAAW,EACzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,uBAAuB,EACvB,SAAS,IAAI,oBAAoB,EAClC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAC,eAAe,EAAC,MAAM,sCAAsC,CAAC;AACrE,OAAO,EAAC,gBAAgB,EAAC,MAAM,iCAAiC,CAAC;AAGjE,OAAO,EAAC,cAAc,EAAE,2BAA2B,EAAC,MAAM,qBAAqB,CAAC;AAEhF,OAAO,EAAC,aAAa,EAAC,MAAM,8BAA8B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ export { ZipLoader } from "./zip-loader.js";
2
+ export { ZipWriter } from "./zip-writer.js";
3
+ export { TarBuilder } from "./tar-builder.js";
4
+ export { parseZipCDFileHeader, makeZipCDHeaderIterator, signature as cdSignature } from "./parse-zip/cd-file-header.js";
5
+ export { parseZipLocalFileHeader, signature as localHeaderSignature } from "./parse-zip/local-file-header.js";
6
+ export { parseEoCDRecord } from "./parse-zip/end-of-central-directory.js";
7
+ export { searchFromTheEnd } from "./parse-zip/search-from-the-end.js";
8
+ export { parseHashTable, makeHashTableFromZipHeaders } from "./hash-file-utility.js";
9
+ export { ZipFileSystem } from "./filesystems/zip-filesystem.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["ZipLoader","ZipWriter","TarBuilder","parseZipCDFileHeader","makeZipCDHeaderIterator","signature","cdSignature","parseZipLocalFileHeader","localHeaderSignature","parseEoCDRecord","searchFromTheEnd","parseHashTable","makeHashTableFromZipHeaders","ZipFileSystem"],"sources":["../src/index.ts"],"sourcesContent":["// loaders.gl, MIT license\n\nexport {ZipLoader} from './zip-loader';\nexport {ZipWriter} from './zip-writer';\nexport {TarBuilder} from './tar-builder';\n\nexport {\n parseZipCDFileHeader,\n makeZipCDHeaderIterator,\n signature as cdSignature\n} from './parse-zip/cd-file-header';\nexport {\n parseZipLocalFileHeader,\n signature as localHeaderSignature\n} from './parse-zip/local-file-header';\nexport {parseEoCDRecord} from './parse-zip/end-of-central-directory';\nexport {searchFromTheEnd} from './parse-zip/search-from-the-end';\n\n// export type {HashElement} from './hash-file-utility';\nexport {parseHashTable, makeHashTableFromZipHeaders} from './hash-file-utility';\n\nexport {ZipFileSystem} from './filesystems/zip-filesystem';\n"],"mappings":"SAEQA,SAAS;AAAA,SACTC,SAAS;AAAA,SACTC,UAAU;AAAA,SAGhBC,oBAAoB,EACpBC,uBAAuB,EACvBC,SAAS,IAAIC,WAAW;AAAA,SAGxBC,uBAAuB,EACvBF,SAAS,IAAIG,oBAAoB;AAAA,SAE3BC,eAAe;AAAA,SACfC,gBAAgB;AAAA,SAGhBC,cAAc,EAAEC,2BAA2B;AAAA,SAE3CC,aAAa"}
@@ -1,4 +1,4 @@
1
- import * as utils from './utils';
1
+ import * as utils from "./utils.js";
2
2
  const structure = {
3
3
  fileName: 100,
4
4
  fileMode: 8,