@loaders.gl/zip 4.2.0-alpha.2 → 4.2.0-alpha.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.
package/dist/dist.dev.js CHANGED
@@ -6975,7 +6975,7 @@ var __exports__ = (() => {
6975
6975
 
6976
6976
  // src/zip-loader.ts
6977
6977
  var import_jszip = __toESM(require_jszip_min(), 1);
6978
- var VERSION = true ? "4.2.0-alpha.2" : "latest";
6978
+ var VERSION = true ? "4.2.0-alpha.4" : "latest";
6979
6979
  var ZipLoader = {
6980
6980
  id: "zip",
6981
6981
  module: "zip",
@@ -7020,7 +7020,7 @@ var __exports__ = (() => {
7020
7020
 
7021
7021
  // src/zip-writer.ts
7022
7022
  var import_jszip2 = __toESM(require_jszip_min(), 1);
7023
- var VERSION2 = true ? "4.2.0-alpha.2" : "latest";
7023
+ var VERSION2 = true ? "4.2.0-alpha.4" : "latest";
7024
7024
  var ZipWriter = {
7025
7025
  name: "Zip Archive",
7026
7026
  id: "zip",
@@ -9354,7 +9354,10 @@ var __exports__ = (() => {
9354
9354
  const textEncoder = new TextEncoder();
9355
9355
  const hashArray = [];
9356
9356
  for await (const cdHeader of zipCDIterator) {
9357
- const filename2 = cdHeader.fileName.split("\\").join("/").toLocaleLowerCase();
9357
+ let filename2 = cdHeader.fileName.split("\\").join("/");
9358
+ if (filename2 !== "3dSceneLayer.json.gz") {
9359
+ filename2 = filename2.toLocaleLowerCase();
9360
+ }
9358
9361
  const arrayBuffer = textEncoder.encode(filename2).buffer;
9359
9362
  const md5 = await md5Hash.hash(arrayBuffer, "hex");
9360
9363
  hashArray.push(concatenateArrayBuffers(hexStringToBuffer(md5), bigintToBuffer(cdHeader.localHeaderOffset)));
@@ -13,7 +13,7 @@ export declare const ZIP_COMPRESSION_HANDLERS: {
13
13
  */
14
14
  export declare class ZipFileSystem implements FileSystem {
15
15
  /** FileProvider instance promise */
16
- protected fileProvider: FileProvider | null;
16
+ fileProvider: FileProvider | null;
17
17
  fileName?: string;
18
18
  archive: IndexedArchive | null;
19
19
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"zip-filesystem.d.ts","sourceRoot":"","sources":["../../src/filesystems/zip-filesystem.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,UAAU,EAAY,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAC,YAAY,EAAiB,MAAM,0BAA0B,CAAC;AAEtE,OAAO,EAAC,eAAe,EAA0B,MAAM,6BAA6B,CAAC;AAGrF,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAEhD,MAAM,MAAM,kBAAkB,GAAG,CAAC,cAAc,EAAE,WAAW,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;AACvF,kDAAkD;AAClD,eAAO,MAAM,wBAAwB,EAAE;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAAA;CASxE,CAAC;AAEF;;;GAGG;AACH,qBAAa,aAAc,YAAW,UAAU;IAC9C,oCAAoC;IACpC,SAAS,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI,CAAQ;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,cAAc,GAAG,IAAI,CAAQ;IAE7C;;;OAGG;gBACS,IAAI,EAAE,YAAY,GAAG,cAAc,GAAG,MAAM;IAkBxD,yBAAyB;IACnB,OAAO;IAMb;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAYlC;;;;OAIG;IACG,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,CAAC;IAKvE;;;;OAIG;IACG,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAsChD;;;;OAIG;YACW,eAAe;CAiB9B"}
1
+ {"version":3,"file":"zip-filesystem.d.ts","sourceRoot":"","sources":["../../src/filesystems/zip-filesystem.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,UAAU,EAAY,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAC,YAAY,EAAiB,MAAM,0BAA0B,CAAC;AAEtE,OAAO,EAAC,eAAe,EAA0B,MAAM,6BAA6B,CAAC;AAGrF,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAEhD,MAAM,MAAM,kBAAkB,GAAG,CAAC,cAAc,EAAE,WAAW,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;AACvF,kDAAkD;AAClD,eAAO,MAAM,wBAAwB,EAAE;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAAA;CASxE,CAAC;AAEF;;;GAGG;AACH,qBAAa,aAAc,YAAW,UAAU;IAC9C,oCAAoC;IAC7B,YAAY,EAAE,YAAY,GAAG,IAAI,CAAQ;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,cAAc,GAAG,IAAI,CAAQ;IAE7C;;;OAGG;gBACS,IAAI,EAAE,YAAY,GAAG,cAAc,GAAG,MAAM;IAkBxD,yBAAyB;IACnB,OAAO;IAMb;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAYlC;;;;OAIG;IACG,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,CAAC;IAKvE;;;;OAIG;IACG,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAsChD;;;;OAIG;YACW,eAAe;CAiB9B"}
@@ -1 +1 @@
1
- {"version":3,"file":"zip-filesystem.js","names":["isBrowser","isFileProvider","FileHandleFile","makeZipCDHeaderIterator","parseZipLocalFileHeader","DeflateCompression","IndexedArchive","ZIP_COMPRESSION_HANDLERS","compressedFile","compression","raw","decompressedData","decompress","ZipFileSystem","constructor","file","fileProvider","fileName","archive","Error","destroy","readdir","fileNames","zipCDIterator","cdHeader","push","stat","filename","cdFileHeader","getCDFileHeader","size","Number","uncompressedSize","fetch","uncompressedFile","getFile","localFileHeader","localHeaderOffset","compressionHandler","compressionMethod","toString","slice","fileDataOffset","compressedSize","response","Response","Object","defineProperty","value","result"],"sources":["../../src/filesystems/zip-filesystem.ts"],"sourcesContent":["// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {FileSystem, isBrowser} from '@loaders.gl/loader-utils';\nimport {FileProvider, isFileProvider} from '@loaders.gl/loader-utils';\nimport {FileHandleFile} from '@loaders.gl/loader-utils';\nimport {ZipCDFileHeader, makeZipCDHeaderIterator} from '../parse-zip/cd-file-header';\nimport {parseZipLocalFileHeader} from '../parse-zip/local-file-header';\nimport {DeflateCompression} from '@loaders.gl/compression';\nimport {IndexedArchive} from './IndexedArchive';\n\nexport type CompressionHandler = (compressedFile: ArrayBuffer) => Promise<ArrayBuffer>;\n/** Handling different compression types in zip */\nexport const ZIP_COMPRESSION_HANDLERS: {[key: number]: CompressionHandler} = {\n /** No compression */\n 0: async (compressedFile) => compressedFile,\n /** Deflation */\n 8: async (compressedFile) => {\n const compression = new DeflateCompression({raw: true});\n const decompressedData = await compression.decompress(compressedFile);\n return decompressedData;\n }\n};\n\n/**\n * FileSystem adapter for a ZIP file\n * Holds FileProvider object that provides random access to archived files\n */\nexport class ZipFileSystem implements FileSystem {\n /** FileProvider instance promise */\n protected fileProvider: FileProvider | null = null;\n public fileName?: string;\n public archive: IndexedArchive | null = null;\n\n /**\n * Constructor\n * @param file - instance of FileProvider or file path string\n */\n constructor(file: FileProvider | IndexedArchive | string) {\n // Try to open file in NodeJS\n if (typeof file === 'string') {\n this.fileName = file;\n if (!isBrowser) {\n this.fileProvider = new FileHandleFile(file);\n } else {\n throw new Error('Cannot open file for random access in a WEB browser');\n }\n } else if (file instanceof IndexedArchive) {\n this.fileProvider = file.fileProvider;\n this.archive = file;\n this.fileName = file.fileName;\n } else if (isFileProvider(file)) {\n this.fileProvider = file;\n }\n }\n\n /** Clean up resources */\n async destroy() {\n if (this.fileProvider) {\n await this.fileProvider.destroy();\n }\n }\n\n /**\n * Get file names list from zip archive\n * @returns array of file names\n */\n async readdir(): Promise<string[]> {\n if (!this.fileProvider) {\n throw new Error('No data detected in the zip archive');\n }\n const fileNames: string[] = [];\n const zipCDIterator = makeZipCDHeaderIterator(this.fileProvider);\n for await (const cdHeader of zipCDIterator) {\n fileNames.push(cdHeader.fileName);\n }\n return fileNames;\n }\n\n /**\n * Get file metadata\n * @param filename - name of a file\n * @returns central directory data\n */\n async stat(filename: string): Promise<ZipCDFileHeader & {size: number}> {\n const cdFileHeader = await this.getCDFileHeader(filename);\n return {...cdFileHeader, size: Number(cdFileHeader.uncompressedSize)};\n }\n\n /**\n * Implementation of fetch against this file system\n * @param filename - name of a file\n * @returns - Response with file data\n */\n async fetch(filename: string): Promise<Response> {\n let uncompressedFile: ArrayBuffer;\n if (this.archive) {\n uncompressedFile = await this.archive.getFile(filename, 'http');\n } else {\n if (!this.fileProvider) {\n throw new Error('No data detected in the zip archive');\n }\n const cdFileHeader = await this.getCDFileHeader(filename);\n const localFileHeader = await parseZipLocalFileHeader(\n cdFileHeader.localHeaderOffset,\n this.fileProvider\n );\n if (!localFileHeader) {\n throw new Error('Local file header has not been found in the zip archive`');\n }\n\n const compressionHandler =\n ZIP_COMPRESSION_HANDLERS[localFileHeader.compressionMethod.toString()];\n if (!compressionHandler) {\n throw Error('Only Deflation compression is supported');\n }\n\n const compressedFile = await this.fileProvider.slice(\n localFileHeader.fileDataOffset,\n localFileHeader.fileDataOffset + localFileHeader.compressedSize\n );\n\n uncompressedFile = await compressionHandler(compressedFile);\n }\n\n const response = new Response(uncompressedFile);\n Object.defineProperty(response, 'url', {\n value: filename ? `${this.fileName || ''}/${filename}` : this.fileName || ''\n });\n return response;\n }\n\n /**\n * Get central directory file header\n * @param filename - name of a file\n * @returns central directory file header\n */\n private async getCDFileHeader(filename: string): Promise<ZipCDFileHeader> {\n if (!this.fileProvider) {\n throw new Error('No data detected in the zip archive');\n }\n const zipCDIterator = makeZipCDHeaderIterator(this.fileProvider);\n let result: ZipCDFileHeader | null = null;\n for await (const cdHeader of zipCDIterator) {\n if (cdHeader.fileName === filename) {\n result = cdHeader;\n break;\n }\n }\n if (!result) {\n throw new Error('File has not been found in the zip archive');\n }\n return result;\n }\n}\n"],"mappings":"AAIA,SAAoBA,SAAS,QAAO,0BAA0B;AAC9D,SAAsBC,cAAc,QAAO,0BAA0B;AACrE,SAAQC,cAAc,QAAO,0BAA0B;AAAC,SAC/BC,uBAAuB;AAAA,SACxCC,uBAAuB;AAC/B,SAAQC,kBAAkB,QAAO,yBAAyB;AAAC,SACnDC,cAAc;AAItB,OAAO,MAAMC,wBAA6D,GAAG;EAE3E,CAAC,EAAE,MAAOC,cAAc,IAAKA,cAAc;EAE3C,CAAC,EAAE,MAAOA,cAAc,IAAK;IAC3B,MAAMC,WAAW,GAAG,IAAIJ,kBAAkB,CAAC;MAACK,GAAG,EAAE;IAAI,CAAC,CAAC;IACvD,MAAMC,gBAAgB,GAAG,MAAMF,WAAW,CAACG,UAAU,CAACJ,cAAc,CAAC;IACrE,OAAOG,gBAAgB;EACzB;AACF,CAAC;AAMD,OAAO,MAAME,aAAa,CAAuB;EAU/CC,WAAWA,CAACC,IAA4C,EAAE;IAAA,KARhDC,YAAY,GAAwB,IAAI;IAAA,KAC3CC,QAAQ;IAAA,KACRC,OAAO,GAA0B,IAAI;IAQ1C,IAAI,OAAOH,IAAI,KAAK,QAAQ,EAAE;MAC5B,IAAI,CAACE,QAAQ,GAAGF,IAAI;MACpB,IAAI,CAACf,SAAS,EAAE;QACd,IAAI,CAACgB,YAAY,GAAG,IAAId,cAAc,CAACa,IAAI,CAAC;MAC9C,CAAC,MAAM;QACL,MAAM,IAAII,KAAK,CAAC,qDAAqD,CAAC;MACxE;IACF,CAAC,MAAM,IAAIJ,IAAI,YAAYT,cAAc,EAAE;MACzC,IAAI,CAACU,YAAY,GAAGD,IAAI,CAACC,YAAY;MACrC,IAAI,CAACE,OAAO,GAAGH,IAAI;MACnB,IAAI,CAACE,QAAQ,GAAGF,IAAI,CAACE,QAAQ;IAC/B,CAAC,MAAM,IAAIhB,cAAc,CAACc,IAAI,CAAC,EAAE;MAC/B,IAAI,CAACC,YAAY,GAAGD,IAAI;IAC1B;EACF;EAGA,MAAMK,OAAOA,CAAA,EAAG;IACd,IAAI,IAAI,CAACJ,YAAY,EAAE;MACrB,MAAM,IAAI,CAACA,YAAY,CAACI,OAAO,CAAC,CAAC;IACnC;EACF;EAMA,MAAMC,OAAOA,CAAA,EAAsB;IACjC,IAAI,CAAC,IAAI,CAACL,YAAY,EAAE;MACtB,MAAM,IAAIG,KAAK,CAAC,qCAAqC,CAAC;IACxD;IACA,MAAMG,SAAmB,GAAG,EAAE;IAC9B,MAAMC,aAAa,GAAGpB,uBAAuB,CAAC,IAAI,CAACa,YAAY,CAAC;IAChE,WAAW,MAAMQ,QAAQ,IAAID,aAAa,EAAE;MAC1CD,SAAS,CAACG,IAAI,CAACD,QAAQ,CAACP,QAAQ,CAAC;IACnC;IACA,OAAOK,SAAS;EAClB;EAOA,MAAMI,IAAIA,CAACC,QAAgB,EAA6C;IACtE,MAAMC,YAAY,GAAG,MAAM,IAAI,CAACC,eAAe,CAACF,QAAQ,CAAC;IACzD,OAAO;MAAC,GAAGC,YAAY;MAAEE,IAAI,EAAEC,MAAM,CAACH,YAAY,CAACI,gBAAgB;IAAC,CAAC;EACvE;EAOA,MAAMC,KAAKA,CAACN,QAAgB,EAAqB;IAC/C,IAAIO,gBAA6B;IACjC,IAAI,IAAI,CAAChB,OAAO,EAAE;MAChBgB,gBAAgB,GAAG,MAAM,IAAI,CAAChB,OAAO,CAACiB,OAAO,CAACR,QAAQ,EAAE,MAAM,CAAC;IACjE,CAAC,MAAM;MACL,IAAI,CAAC,IAAI,CAACX,YAAY,EAAE;QACtB,MAAM,IAAIG,KAAK,CAAC,qCAAqC,CAAC;MACxD;MACA,MAAMS,YAAY,GAAG,MAAM,IAAI,CAACC,eAAe,CAACF,QAAQ,CAAC;MACzD,MAAMS,eAAe,GAAG,MAAMhC,uBAAuB,CACnDwB,YAAY,CAACS,iBAAiB,EAC9B,IAAI,CAACrB,YACP,CAAC;MACD,IAAI,CAACoB,eAAe,EAAE;QACpB,MAAM,IAAIjB,KAAK,CAAC,0DAA0D,CAAC;MAC7E;MAEA,MAAMmB,kBAAkB,GACtB/B,wBAAwB,CAAC6B,eAAe,CAACG,iBAAiB,CAACC,QAAQ,CAAC,CAAC,CAAC;MACxE,IAAI,CAACF,kBAAkB,EAAE;QACvB,MAAMnB,KAAK,CAAC,yCAAyC,CAAC;MACxD;MAEA,MAAMX,cAAc,GAAG,MAAM,IAAI,CAACQ,YAAY,CAACyB,KAAK,CAClDL,eAAe,CAACM,cAAc,EAC9BN,eAAe,CAACM,cAAc,GAAGN,eAAe,CAACO,cACnD,CAAC;MAEDT,gBAAgB,GAAG,MAAMI,kBAAkB,CAAC9B,cAAc,CAAC;IAC7D;IAEA,MAAMoC,QAAQ,GAAG,IAAIC,QAAQ,CAACX,gBAAgB,CAAC;IAC/CY,MAAM,CAACC,cAAc,CAACH,QAAQ,EAAE,KAAK,EAAE;MACrCI,KAAK,EAAErB,QAAQ,GAAI,GAAE,IAAI,CAACV,QAAQ,IAAI,EAAG,IAAGU,QAAS,EAAC,GAAG,IAAI,CAACV,QAAQ,IAAI;IAC5E,CAAC,CAAC;IACF,OAAO2B,QAAQ;EACjB;EAOA,MAAcf,eAAeA,CAACF,QAAgB,EAA4B;IACxE,IAAI,CAAC,IAAI,CAACX,YAAY,EAAE;MACtB,MAAM,IAAIG,KAAK,CAAC,qCAAqC,CAAC;IACxD;IACA,MAAMI,aAAa,GAAGpB,uBAAuB,CAAC,IAAI,CAACa,YAAY,CAAC;IAChE,IAAIiC,MAA8B,GAAG,IAAI;IACzC,WAAW,MAAMzB,QAAQ,IAAID,aAAa,EAAE;MAC1C,IAAIC,QAAQ,CAACP,QAAQ,KAAKU,QAAQ,EAAE;QAClCsB,MAAM,GAAGzB,QAAQ;QACjB;MACF;IACF;IACA,IAAI,CAACyB,MAAM,EAAE;MACX,MAAM,IAAI9B,KAAK,CAAC,4CAA4C,CAAC;IAC/D;IACA,OAAO8B,MAAM;EACf;AACF"}
1
+ {"version":3,"file":"zip-filesystem.js","names":["isBrowser","isFileProvider","FileHandleFile","makeZipCDHeaderIterator","parseZipLocalFileHeader","DeflateCompression","IndexedArchive","ZIP_COMPRESSION_HANDLERS","compressedFile","compression","raw","decompressedData","decompress","ZipFileSystem","constructor","file","fileProvider","fileName","archive","Error","destroy","readdir","fileNames","zipCDIterator","cdHeader","push","stat","filename","cdFileHeader","getCDFileHeader","size","Number","uncompressedSize","fetch","uncompressedFile","getFile","localFileHeader","localHeaderOffset","compressionHandler","compressionMethod","toString","slice","fileDataOffset","compressedSize","response","Response","Object","defineProperty","value","result"],"sources":["../../src/filesystems/zip-filesystem.ts"],"sourcesContent":["// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {FileSystem, isBrowser} from '@loaders.gl/loader-utils';\nimport {FileProvider, isFileProvider} from '@loaders.gl/loader-utils';\nimport {FileHandleFile} from '@loaders.gl/loader-utils';\nimport {ZipCDFileHeader, makeZipCDHeaderIterator} from '../parse-zip/cd-file-header';\nimport {parseZipLocalFileHeader} from '../parse-zip/local-file-header';\nimport {DeflateCompression} from '@loaders.gl/compression';\nimport {IndexedArchive} from './IndexedArchive';\n\nexport type CompressionHandler = (compressedFile: ArrayBuffer) => Promise<ArrayBuffer>;\n/** Handling different compression types in zip */\nexport const ZIP_COMPRESSION_HANDLERS: {[key: number]: CompressionHandler} = {\n /** No compression */\n 0: async (compressedFile) => compressedFile,\n /** Deflation */\n 8: async (compressedFile) => {\n const compression = new DeflateCompression({raw: true});\n const decompressedData = await compression.decompress(compressedFile);\n return decompressedData;\n }\n};\n\n/**\n * FileSystem adapter for a ZIP file\n * Holds FileProvider object that provides random access to archived files\n */\nexport class ZipFileSystem implements FileSystem {\n /** FileProvider instance promise */\n public fileProvider: FileProvider | null = null;\n public fileName?: string;\n public archive: IndexedArchive | null = null;\n\n /**\n * Constructor\n * @param file - instance of FileProvider or file path string\n */\n constructor(file: FileProvider | IndexedArchive | string) {\n // Try to open file in NodeJS\n if (typeof file === 'string') {\n this.fileName = file;\n if (!isBrowser) {\n this.fileProvider = new FileHandleFile(file);\n } else {\n throw new Error('Cannot open file for random access in a WEB browser');\n }\n } else if (file instanceof IndexedArchive) {\n this.fileProvider = file.fileProvider;\n this.archive = file;\n this.fileName = file.fileName;\n } else if (isFileProvider(file)) {\n this.fileProvider = file;\n }\n }\n\n /** Clean up resources */\n async destroy() {\n if (this.fileProvider) {\n await this.fileProvider.destroy();\n }\n }\n\n /**\n * Get file names list from zip archive\n * @returns array of file names\n */\n async readdir(): Promise<string[]> {\n if (!this.fileProvider) {\n throw new Error('No data detected in the zip archive');\n }\n const fileNames: string[] = [];\n const zipCDIterator = makeZipCDHeaderIterator(this.fileProvider);\n for await (const cdHeader of zipCDIterator) {\n fileNames.push(cdHeader.fileName);\n }\n return fileNames;\n }\n\n /**\n * Get file metadata\n * @param filename - name of a file\n * @returns central directory data\n */\n async stat(filename: string): Promise<ZipCDFileHeader & {size: number}> {\n const cdFileHeader = await this.getCDFileHeader(filename);\n return {...cdFileHeader, size: Number(cdFileHeader.uncompressedSize)};\n }\n\n /**\n * Implementation of fetch against this file system\n * @param filename - name of a file\n * @returns - Response with file data\n */\n async fetch(filename: string): Promise<Response> {\n let uncompressedFile: ArrayBuffer;\n if (this.archive) {\n uncompressedFile = await this.archive.getFile(filename, 'http');\n } else {\n if (!this.fileProvider) {\n throw new Error('No data detected in the zip archive');\n }\n const cdFileHeader = await this.getCDFileHeader(filename);\n const localFileHeader = await parseZipLocalFileHeader(\n cdFileHeader.localHeaderOffset,\n this.fileProvider\n );\n if (!localFileHeader) {\n throw new Error('Local file header has not been found in the zip archive`');\n }\n\n const compressionHandler =\n ZIP_COMPRESSION_HANDLERS[localFileHeader.compressionMethod.toString()];\n if (!compressionHandler) {\n throw Error('Only Deflation compression is supported');\n }\n\n const compressedFile = await this.fileProvider.slice(\n localFileHeader.fileDataOffset,\n localFileHeader.fileDataOffset + localFileHeader.compressedSize\n );\n\n uncompressedFile = await compressionHandler(compressedFile);\n }\n\n const response = new Response(uncompressedFile);\n Object.defineProperty(response, 'url', {\n value: filename ? `${this.fileName || ''}/${filename}` : this.fileName || ''\n });\n return response;\n }\n\n /**\n * Get central directory file header\n * @param filename - name of a file\n * @returns central directory file header\n */\n private async getCDFileHeader(filename: string): Promise<ZipCDFileHeader> {\n if (!this.fileProvider) {\n throw new Error('No data detected in the zip archive');\n }\n const zipCDIterator = makeZipCDHeaderIterator(this.fileProvider);\n let result: ZipCDFileHeader | null = null;\n for await (const cdHeader of zipCDIterator) {\n if (cdHeader.fileName === filename) {\n result = cdHeader;\n break;\n }\n }\n if (!result) {\n throw new Error('File has not been found in the zip archive');\n }\n return result;\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
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;AAClC,OAAO,EAAC,eAAe,EAA0B,MAAM,4BAA4B,CAAC;AAEpF;;;;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,CAGjC;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,aAAa,EAAE,aAAa,CAAC,eAAe,CAAC,GAC5C,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAcjC;AAED,mCAAmC;AACnC,KAAK,YAAY,GAAG;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,aAAa,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,GAClE,OAAO,CAAC,WAAW,CAAC,CAkBtB"}
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;AAClC,OAAO,EAAC,eAAe,EAA0B,MAAM,4BAA4B,CAAC;AAEpF;;;;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,CAGjC;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,aAAa,EAAE,aAAa,CAAC,eAAe,CAAC,GAC5C,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAcjC;AAED,mCAAmC;AACnC,KAAK,YAAY,GAAG;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,aAAa,EAAE,aAAa,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,GAClE,OAAO,CAAC,WAAW,CAAC,CAwBtB"}
@@ -35,7 +35,10 @@ export async function composeHashFile(zipCDIterator) {
35
35
  const textEncoder = new TextEncoder();
36
36
  const hashArray = [];
37
37
  for await (const cdHeader of zipCDIterator) {
38
- const filename = cdHeader.fileName.split('\\').join('/').toLocaleLowerCase();
38
+ let filename = cdHeader.fileName.split('\\').join('/');
39
+ if (filename !== '3dSceneLayer.json.gz') {
40
+ filename = filename.toLocaleLowerCase();
41
+ }
39
42
  const arrayBuffer = textEncoder.encode(filename).buffer;
40
43
  const md5 = await md5Hash.hash(arrayBuffer, 'hex');
41
44
  hashArray.push(concatenateArrayBuffers(hexStringToBuffer(md5), bigintToBuffer(cdHeader.localHeaderOffset)));
@@ -1 +1 @@
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","getHashTable","md5Hash","textEncoder","TextEncoder","hashTable","cdHeader","filename","fileName","split","toLocaleLowerCase","encode","md5","localHeaderOffset","composeHashFile","hashArray","push","hexStringToBuffer","bigintToBuffer","bufferArray","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 {ZipCDFileHeader, 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 return getHashTable(zipCDIterator);\n}\n\n/**\n * creates hash table from file offset iterator\n * @param zipCDIterator iterator to use\n * @returns hash table\n */\nexport async function getHashTable(\n zipCDIterator: AsyncIterable<ZipCDFileHeader>\n): Promise<Record<string, bigint>> {\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/** item of the file offset list */\ntype FileListItem = {\n fileName: string;\n localHeaderOffset: bigint;\n};\n\n/**\n * creates hash file that later can be added to the SLPK archive\n * @param zipCDIterator iterator to use\n * @returns ArrayBuffer containing hash file\n */\nexport async function composeHashFile(\n zipCDIterator: AsyncIterable<FileListItem> | Iterable<FileListItem>\n): Promise<ArrayBuffer> {\n const md5Hash = new MD5Hash();\n const textEncoder = new TextEncoder();\n\n const hashArray: ArrayBuffer[] = [];\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 hashArray.push(\n concatenateArrayBuffers(hexStringToBuffer(md5), bigintToBuffer(cdHeader.localHeaderOffset))\n );\n }\n\n const bufferArray = hashArray.sort(compareHashes);\n\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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"}
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","getHashTable","md5Hash","textEncoder","TextEncoder","hashTable","cdHeader","filename","fileName","split","toLocaleLowerCase","encode","md5","localHeaderOffset","composeHashFile","hashArray","push","hexStringToBuffer","bigintToBuffer","bufferArray","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 {ZipCDFileHeader, 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 return getHashTable(zipCDIterator);\n}\n\n/**\n * creates hash table from file offset iterator\n * @param zipCDIterator iterator to use\n * @returns hash table\n */\nexport async function getHashTable(\n zipCDIterator: AsyncIterable<ZipCDFileHeader>\n): Promise<Record<string, bigint>> {\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/** item of the file offset list */\ntype FileListItem = {\n fileName: string;\n localHeaderOffset: bigint;\n};\n\n/**\n * creates hash file that later can be added to the SLPK archive\n * @param zipCDIterator iterator to use\n * @returns ArrayBuffer containing hash file\n */\nexport async function composeHashFile(\n zipCDIterator: AsyncIterable<FileListItem> | Iterable<FileListItem>\n): Promise<ArrayBuffer> {\n const md5Hash = new MD5Hash();\n const textEncoder = new TextEncoder();\n\n const hashArray: ArrayBuffer[] = [];\n\n for await (const cdHeader of zipCDIterator) {\n let filename = cdHeader.fileName.split('\\\\').join('/');\n // I3S edge case. All files should be lower case by spec. However, ArcGIS\n // and official i3s_converter https://github.com/Esri/i3s-spec/blob/master/i3s_converter/i3s_converter_ReadMe.md\n // expect `3dSceneLayer.json.gz` in camel case\n if (filename !== '3dSceneLayer.json.gz') {\n filename = filename.toLocaleLowerCase();\n }\n const arrayBuffer = textEncoder.encode(filename).buffer;\n const md5 = await md5Hash.hash(arrayBuffer, 'hex');\n hashArray.push(\n concatenateArrayBuffers(hexStringToBuffer(md5), bigintToBuffer(cdHeader.localHeaderOffset))\n );\n }\n\n const bufferArray = hashArray.sort(compareHashes);\n\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
@@ -1381,7 +1381,10 @@ async function composeHashFile(zipCDIterator) {
1381
1381
  const textEncoder = new TextEncoder();
1382
1382
  const hashArray = [];
1383
1383
  for await (const cdHeader of zipCDIterator) {
1384
- const filename = cdHeader.fileName.split("\\").join("/").toLocaleLowerCase();
1384
+ let filename = cdHeader.fileName.split("\\").join("/");
1385
+ if (filename !== "3dSceneLayer.json.gz") {
1386
+ filename = filename.toLocaleLowerCase();
1387
+ }
1385
1388
  const arrayBuffer = textEncoder.encode(filename).buffer;
1386
1389
  const md5 = await md5Hash.hash(arrayBuffer, "hex");
1387
1390
  hashArray.push(
@@ -1,5 +1,5 @@
1
1
  import JSZip from 'jszip';
2
- const VERSION = typeof "4.2.0-alpha.2" !== 'undefined' ? "4.2.0-alpha.2" : 'latest';
2
+ const VERSION = typeof "4.2.0-alpha.4" !== 'undefined' ? "4.2.0-alpha.4" : 'latest';
3
3
  export const ZipLoader = {
4
4
  id: 'zip',
5
5
  module: 'zip',
@@ -1,5 +1,5 @@
1
1
  import JSZip from 'jszip';
2
- const VERSION = typeof "4.2.0-alpha.2" !== 'undefined' ? "4.2.0-alpha.2" : 'latest';
2
+ const VERSION = typeof "4.2.0-alpha.4" !== 'undefined' ? "4.2.0-alpha.4" : 'latest';
3
3
  export const ZipWriter = {
4
4
  name: 'Zip Archive',
5
5
  id: 'zip',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loaders.gl/zip",
3
- "version": "4.2.0-alpha.2",
3
+ "version": "4.2.0-alpha.4",
4
4
  "description": "Zip Archive Loader",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -38,11 +38,11 @@
38
38
  "build-bundle": "ocular-bundle ./src/index.ts"
39
39
  },
40
40
  "dependencies": {
41
- "@loaders.gl/compression": "4.2.0-alpha.2",
42
- "@loaders.gl/crypto": "4.2.0-alpha.2",
43
- "@loaders.gl/loader-utils": "4.2.0-alpha.2",
41
+ "@loaders.gl/compression": "4.2.0-alpha.4",
42
+ "@loaders.gl/crypto": "4.2.0-alpha.4",
43
+ "@loaders.gl/loader-utils": "4.2.0-alpha.4",
44
44
  "jszip": "^3.1.5",
45
45
  "md5": "^2.3.0"
46
46
  },
47
- "gitHead": "d66a6a4626ea84c5f2cad5fa5cf7ebb6943c57c8"
47
+ "gitHead": "6c52dee5c3f005648a394cc4aee7fc37005c8e83"
48
48
  }
@@ -29,7 +29,7 @@ export const ZIP_COMPRESSION_HANDLERS: {[key: number]: CompressionHandler} = {
29
29
  */
30
30
  export class ZipFileSystem implements FileSystem {
31
31
  /** FileProvider instance promise */
32
- protected fileProvider: FileProvider | null = null;
32
+ public fileProvider: FileProvider | null = null;
33
33
  public fileName?: string;
34
34
  public archive: IndexedArchive | null = null;
35
35
 
@@ -91,7 +91,13 @@ export async function composeHashFile(
91
91
  const hashArray: ArrayBuffer[] = [];
92
92
 
93
93
  for await (const cdHeader of zipCDIterator) {
94
- const filename = cdHeader.fileName.split('\\').join('/').toLocaleLowerCase();
94
+ let filename = cdHeader.fileName.split('\\').join('/');
95
+ // I3S edge case. All files should be lower case by spec. However, ArcGIS
96
+ // and official i3s_converter https://github.com/Esri/i3s-spec/blob/master/i3s_converter/i3s_converter_ReadMe.md
97
+ // expect `3dSceneLayer.json.gz` in camel case
98
+ if (filename !== '3dSceneLayer.json.gz') {
99
+ filename = filename.toLocaleLowerCase();
100
+ }
95
101
  const arrayBuffer = textEncoder.encode(filename).buffer;
96
102
  const md5 = await md5Hash.hash(arrayBuffer, 'hex');
97
103
  hashArray.push(